Laravel hasManyThrough [英] Laravel hasManyThrough
问题描述
我有三个表:
预订
-id(int)
- 其他字段
元
-id(int)
-booking_id(int)
-metatype_id(int)
-some其他字段
MetaType
-id(int)
-name(string)
-some其他字段
我想要得到的是一个雄辩的模型,允许我拥有一个具有MetaType类型的多个Meta记录的单个预订记录。我认为hasManyThrough可能已经解决了这一点,但现在我认为也许这不是最好的方法。
在我的预订模式我有
public function bookingmeta(){
return $ this-> hasMany('bookingmeta','booking_id');
}
public function bookingmetatype(){
return $ this-> hasManyThrough('bookingmetatype','bookingmeta','booking_id','bookingmetatype_id');
}
但是这无法生成正确的SQL并失败。我得到
选择`new_bookingmetatype` *,`new_bookingmeta`.`booking_id`
from`new_bookingmetatype`
内连接`new_bookingmeta`
on`new_bookingmeta```bookingmetatype_id` =`new_bookingmetatype`.`id`
其中`new_bookingmeta`.`booking_id` in(57103)
而我真正想要实现的是
code>从`new_bookingmetatype'
内连接`new_bookingmeta`
``new_bookingmeta````````` new_bookingmetatype`.`bookingmetatype_id $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ >如果有人能指出我正确的方向,我真的很感激。谢谢。解决方案
hasManyThrough
根本不是。它只适用于这样的关系:A hasMany / hasOne B,B hasMany / hasOne C,则A hasManyThrough C(through B)
你在这里有很多到很多(
belongsToMany
),
meta
作为枢轴表。
所以你可以这样做(假设
meta
是表名,Booking和MetaType是模型)://预订模型
public function meta()
{
return $ this-> belongsToMany('MetaType','meta','booking_id','metatype_id')
- > ; withPivot([您需要从元表的字段阵列]);
}
然后,您可以访问所有关联的MetaType:
$ booking-> meta; //收集MetaType模型
像这样查询(渴望加载):
$ reservation = Booking :: with(['meta'=> function($ q){
//查询相关表
$ q->其中('someFieldOnMetaTypeTable','someValue')
//和/或数据透视表
- > wherePivot('someFieldOnMetaTable',' anotherValue');
}]) - > first();
或在相关表上设置约束来过滤预订:
$ booking = Booking :: whereHas('meta',function($ q){
//查询相关表
$ q-> where('someFieldOnMetaTypeTable','someValue')
//和/或枢轴表
- >其中('meta.someFieldOnMetaTable','anotherValue');
}) - > first();
注意:
wherePivot
只有当你渴望加载关系,所以你不能在whereHas
关闭中使用它。I'm struggling to get my head around a hasManyThrough concept with laravel. I have three tables:
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.
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
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.
解决方案
hasManyThrough
is not the way at all. It works only for relations like this:A hasMany/hasOne B, B hasMany/hasOne C, then A hasManyThrough C (through B)
What you have here is a many to many (
belongsToMany
), withmeta
being the pivot table.So you can do this (assuming
meta
is table name, Booking and MetaType are models):// 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:
$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 inwhereHas
closure.这篇关于Laravel hasManyThrough的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!