Laravel hasManyThrough
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24994640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel hasManyThrough
提问by Greg
I'm struggling to get my head around a hasManyThrough concept with laravel. I have three tables:
我正在努力理解 laravel 的 hasManyThrough 概念。我有三个表:
Bookings
-id (int)
-some other fields
Meta
-id (int)
-booking_id (int)
-metatype_id (int)
-some other fields
MetaType
-id (int)
-name (string)
-some other fields
What I am trying to get is an Eloquent model that allows me to have a single booking record with multiple Meta records of type MetaType. I thought that hasManyThrough might have solved this, but now I am thinking that perhaps this is not the best way.
我想要得到的是一个 Eloquent 模型,它允许我拥有一个带有多个 MetaType 类型的 Meta 记录的单一预订记录。我认为 hasManyThrough 可能已经解决了这个问题,但现在我认为这可能不是最好的方法。
In my booking model I have
在我的预订模型中,我有
public function bookingmeta() {
return $this->hasMany('bookingmeta','booking_id');
}
public function bookingmetatype() {
return $this->hasManyThrough('bookingmetatype','bookingmeta','booking_id','bookingmetatype_id');
}
But this fails to generate the correct SQL and fails. I get
但这无法生成正确的 SQL 并失败。我得到
select `new_bookingmetatype`.*, `new_bookingmeta`.`booking_id`
from `new_bookingmetatype`
inner join `new_bookingmeta`
on `new_bookingmeta`.`bookingmetatype_id` = `new_bookingmetatype`.`id`
where `new_bookingmeta`.`booking_id` in (57103)
Whereas what I am really trying to achieve is
而我真正想要实现的是
select `new_bookingmetatype`.*, `new_bookingmeta`.`booking_id`
from `new_bookingmetatype`
inner join `new_bookingmeta`
on `new_bookingmeta`.`id` = `new_bookingmetatype`.`bookingmetatype_id`
where `new_bookingmeta`.`booking_id` in (57103)
If anyone can point me in the right direction I'd really appreciate it. Thanks.
如果有人能指出我正确的方向,我将不胜感激。谢谢。
回答by Jarek Tkaczyk
hasManyThrough
is not the way at all. It works only for relations like this:
hasManyThrough
根本不是办法。它只适用于这样的关系:
A hasMany/hasOne B, B hasMany/hasOne C, then A hasManyThrough C (through B)
What you have here is a many to many (belongsToMany
), with meta
being the pivot table.
您在这里拥有的是多对多 ( belongsToMany
),meta
作为数据透视表。
So you can do this (assuming meta
is table name, Booking and MetaType are models):
所以你可以这样做(假设meta
是表名,Booking 和 MetaType 是模型):
// Booking model
public function meta()
{
return $this->belongsToMany('MetaType', 'meta', 'booking_id', 'metatype_id')
->withPivot([ ARRAY OF FIELDS YOU NEED FROM meta TABLE ]);
}
Then you can access all associated MetaType:
然后你可以访问所有关联的 MetaType:
$booking->meta; // collection of MetaType models
query it like this (eager loading):
像这样查询(急切加载):
$booking = Booking::with(['meta' => function ($q) {
// query related table
$q->where('someFieldOnMetaTypeTable', 'someValue')
// and / or pivot table
->wherePivot('someFieldOnMetaTable', 'anotherValue');
}])->first();
or set constraints on the related table to filter the Booking:
或在相关表上设置约束以过滤预订:
$booking = Booking::whereHas('meta', function ($q) {
// query related table
$q->where('someFieldOnMetaTypeTable', 'someValue')
// and / or pivot table
->where('meta.someFieldOnMetaTable', 'anotherValue');
})->first();
Note: wherePivot
works only when you eager load the relationship, so you can't use it in whereHas
closure.
注意:wherePivot
仅当您急切加载关系时才有效,因此您不能在whereHas
闭包中使用它。