我找到了一个解决方案,但它并不是非常简单。我已经在下面发布了,但我先发布了我认为更好的解决方案。
您不能直接从列表中访问制造商,因为制造商仅适用于模型。尽管您可以从列表对象中预先加载制造商关系,但请参见下文。
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_ids 填充 ?。所以这会返回结果,但通常是不正确的结果。然后我的目标是更改我从中选择的基表。这个值是模型派生出来的,所以我把传入的模型改成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 (?)
从这里开始,我想将查询的列限制为制造商列,为此我添加了选择规范。这将关系带到:
return $this->belongsTo('Model', 'model_id')
->join('manufacturers', 'manufacturers.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 themodelstable in the where clause. I created a new instance of Manufacturer and set the table tomodels` 并手动创建关系。
请务必注意,保存无效。
$listing = Listing::find(1);
$listing->manufacturer()->associate(Manufacturer::create([]));
$listing->save();
这将创建一个新的制造商,然后将listings.model_id 更新为新制造商的 ID。