Laravel hasManyThrough [英] Laravel hasManyThrough

查看:1404
本文介绍了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), with meta 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 in whereHas closure.

这篇关于Laravel hasManyThrough的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆