我有一个模型列表,它通过其belongsTo("模型")关系继承,应该固有地属于其相应模型所属的制造商。
以下是我的上市模型:
public function model()
{
return $this->belongsTo('Model', 'model_id');
}
public function manufacturer()
{
return $this->belongsTo('Manufacturer', 'models.manufacturer_id');
/*
$manufacturer_id = $this->model->manufacturer_id;
return Manufacturer::find($manufacturer_id)->name;*/
}
和我的制造商型号:
public function listings()
{
return $this->hasManyThrough('Listing', 'Model', 'manufacturer_id', 'model_id');
}
public function models()
{
return $this->hasMany('Model', 'manufacturer_id');
}
我可以在视图中回显$listing->model->name,但不能回显$listing->manufacturer->name。这引发了一个错误。我尝试了Listing模型中注释掉的2行,只是为了获得效果,这样我就可以回显$Listing->manufacturer(),这会起作用,但这并不能正确地建立它们的关系。我该怎么做?谢谢
修订上市模型(感谢回答者):
public function model()
{
return $this->belongsTo('Model', 'model_id');
}
public function manufacturer()
{
return $this->belongsTo('Model', 'model_id')
->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id');
}
我找到了一个解决方案,但它并不是非常直接。我在下面发布了它,但我首先发布了我认为更好的解决方案。
您不应该能够直接从列表中访问制造商,因为制造商仅适用于模型。尽管您可以从列表对象中加载制造商关系,但请参见下文。
class Listing extends Eloquent
{
public function model()
{
return $this->belongsTo('Model', 'model_id');
}
}
class Model extends Eloquent
{
public function manufacturer()
{
return $this->belongsTo('manufacturer');
}
}
class Manufacturer extends Eloquent
{
}
$listings = Listing::with('model.manufacturer')->all();
foreach($listings as $listing) {
echo $listing->model->name . ' by ' . $listing->model->manufacturer->name;
}
它花了一点欺骗,让你要求的解决方案发挥作用。解决方案如下:
public function manufacturer()
{
$instance = new Manufacturer();
$instance->setTable('models');
$query = $instance->newQuery();
return (new BelongsTo($query, $this, 'model_id', $instance->getKeyName(), 'manufacturer'))
->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id')
->select(DB::raw('manufacturers.*'));
}
我首先处理查询并从中构建响应。我想要创建的查询大致如下:
SELECT * FROM manufacturers ma
JOIN models m on m.manufacturer_id = ma.id
WHERE m.id in (?)
通常通过执行return $this->belongsTo('Manufacturer');
创建的查询
select * from `manufacturers` where `manufacturers`.`id` in (?)
?
将替换为列表表中manufacturer_id
列的值。此列不存在,因此将插入一个0,并且您永远不会返回制造商。
在我想要重新创建的查询中,我受到了models.id
的约束。通过定义外键,我可以很容易地在我的关系中获取该值。所以这种关系变成了
return $this->belongsTo('Manufacturer', 'model_id');
这会生成与以前相同的查询,但会使用model_id填充?
。因此,这会返回结果,但通常是不正确的结果。然后,我打算更改从中选择的基表。这个值是从模型中导出的,所以我将传入的模型更改为Model
。
return $this->belongsTo('Model', 'model_id');
我们现在已经模仿了模型关系,所以我真的没有取得任何进展,这太棒了。但至少现在,我可以加入制造商的行列。所以我再次更新了关系:
return $this->belongsTo('Model', 'model_id')
->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id');
这让我们又近了一步,生成了以下查询:
select * from `models`
inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id`
where `models`.`id` in (?)
从这里开始,我想将查询的列限制为制造商列,为此,我添加了select规范。这将关系带到:
return$this->belongsTo('Model','Model_id')->join('manufacturers','manufactures.id','=','models.manufacturer_id')->select(DB::raw('manufacturers.*'));
并将查询发送到
select manufacturers.* from `models`
inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id`
where `models`.`id` in (?)
现在我们有一个100%有效的查询,但是从关系中返回的对象的类型是Model
,而不是Manufacturer
。这就是最后一点技巧。我需要返回一个Manufacturer, but wanted it to constrain by the
模型table in the where clause. I created a new instance of Manufacturer and set the table to
模型并手动创建关系。
需要注意的是,保存将不起作用。
$listing = Listing::find(1);
$listing->manufacturer()->associate(Manufacturer::create([]));
$listing->save();
这将创建一个新的制造商,然后将listings.model_id
更新为新制造商的id。
我想这可能会有所帮助,它帮助了我:
class Car extends Model
{
public function mechanical()
{
return $this->belongsTo(Mechanical::class);
}
}
class CarPiece extends Model
{
public function car()
{
return $this->belongsTo(Car::class);
}
public function mechanical()
{
return $this->car->mechanical();
}
}
至少,正是这种需要让我想到了belongsToThrough 的存在
您可以这样做(学生组-用户-民意调查结果):
// poll result
public function studentGroup(): HasOneDeep
{
return $this->hasOneDeepFromRelations($this->user(), (new User())->studentGroup());
}