Laravel:如何从具有关系的 3 个表中获取数据
Posted
技术标签:
【中文标题】Laravel:如何从具有关系的 3 个表中获取数据【英文标题】:Laravel: How to get data from 3 tables with relationship 【发布时间】:2020-01-06 11:04:26 【问题描述】:我有 3 张桌子:
Customers
Sales
Contacts
contacts
表中没有任何更新操作。每个进程在contacts
表中打开一条新记录。因此,一个用户在contacts
表中可以有多个记录。
这是我在模型中的关系:
Customer
public function contacts()
return $this->hasMany(Contact::class);
public function sales()
return $this->hasMany(Sale::class);
Contact
public function customer()
return $this->belongsTo('App\Customer', 'customer_id');
Sale
public function customer()
return $this->belongsTo('App\Customer');
我想获得contacts
表的最新记录,并使其与其他相关表连接。
这是我尝试过的查询:
$record = Contact::groupBy('customer_id')
->select(DB::raw('max(id)'));
$result = Customer::query();
$result->where('is_active', 'YES');
$result->with('sales');
$result->whereHas('contacts', function ($q) use($record)
return $q->whereIn('id', $record)->where('result', 'UNCALLED');
);
return $result->get();
在刀片文件中,我在foreach
循环中得到了一些结果。但是,我无法从sales
和contacts
表中获取相关数据。
@foreach($result as $item)
@foreach($item->sales as $sale) // Has no output and gives error: Invalid argument supplied for foreach()
@foreach($item->contacts as $contact) // Has no output and gives error: Invalid argument supplied for foreach()
谁能帮助我如何显示销售和联系日期?或者对如何提高此代码质量有任何想法?
【问题讨论】:
你有没有在你的 eloquent 模型中尝试过protected $with
属性?
快速笔记;关系名称应反映返回的结果数量。你有contact
和sale
,它们都使用hasMany()
并且返回不止一个,所以它们真的应该是contacts
和sales
以避免混淆。 customer
很好,因为 belongsTo()
固有地返回一条记录。
@TimLewis 是的,你是对的。抱歉拼错了。我更正了。
别担心!只要确保也修复参考; $item->sales
而不是 $item->sale
和 $item->contacts
而不是 $item->contact
@MadameGreenPea 你如何将结果发送到视图?
【参考方案1】:
如果您想要联系人的最新记录,您可以在Customer
模型上声明另一个关系,例如:
public function latest_contact()
return $this->hasOne(Contact::class)->latest('contact_date');
顺便说一句,如果你有一个hasMany
,你总是可以声明一个或多个hasOne
附加关系,外键使用是相同的。
通过这种方式,您可以使用您的Customer
模型检索latest_contact
渴望加载:
$customer = Customer::with('latest_contact')->find($id);
或者在您的查询中使用这种关系,例如:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->whereHas('last_contact', function ($q)
return $q->where('result', 'UNCALLED');
)->get();
或者说:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->with('last_contact', function ($q)
return $q->where('result', 'UNCALLED');
)->get();
如果您愿意,可以声明 last_contact
和附加的 where
:
public function latest_contact()
return $this->hasOne(Contact::class)
->where('result', 'UNCALLED')
->latest('contact_date');
这样所有其他查询应该更容易。 我希望这可以帮助你。
【讨论】:
谢谢。但是,我仍然无法在视图文件中获得销售日期和联系日期。所以,不幸的是,结果是一样的。我不明白为什么。 这个想法很简单:通过hasMany
关系,您可以在具有附加条件的同一模型上声明其他hasOne
和hasMany
,尝试使用该想法和您的数据,您的查询应该更容易。【参考方案2】:
我不确定,但您可以尝试执行以下操作吗:
return Customer::where('is_active', 'YES')
->with([
'sale',
'contact' => function ($query) use($record)
return $query->whereIn('id', $record)->where('result', 'UNCALLED');
])->get();
【讨论】:
这将返回所有活动的Customer
记录,但最初的问题是使用->whereHas()
添加额外的过滤,所以这是一种不正确的方法。你导致->with()
和->whereHas()
同时使用来限制->contact
的返回结果,但是省略它是错误的。以上是关于Laravel:如何从具有关系的 3 个表中获取数据的主要内容,如果未能解决你的问题,请参考以下文章
从3个表中检索数据如何使用Laravel中的第一个表从最后一个表中检索数据
Laravel 5.2 Eloquent ORM 从 3 个表中获取数据