假设我有orders
表和users
表以及guests
表,适用于接受来自users
和guests
的订单的公司。
我在is_guest
表上也有一个orders
布尔值,让我快速了解订单是由客人还是注册用户做出的。
我有一个名为customer
的模型方法,它返回如此的雄辩关系:
public function customer()
{
return $this->is_guest ? $this->belongsTo('Guest', 'user_id') : $this->belongsTo('User', 'user_id');
}
当我将orders
传递给视图并访问客户的数据时,这非常有效:
// Maps to either $order->user->firstname OR $order->guest->firstname
echo $order->customer->firstname;
但是当我在使用预先加载时尝试使用此功能时,它不能正常工作:
$orders = Order::with('customer')->get();
return Response::make($orders);
它只返回 user
或guest
的热切加载客户数据,而不会同时返回两者。
我想知道为什么会这样,以及如何绕过它?
是因为热切加载的工作方式 - 它只调用customer()
方法一次就像它只访问数据库一次,所以无论查询的第一个结果是什么,它还会用它来确定查询的其余部分吗?
如果我尝试使用所有客户的详细信息获取所有order
数据的JSON响应,我该怎么做?
感谢。
是的,事实证明我通过添加条件来滥用Laravel关系方法。 使用多态关系是一种更好的方法,如@lukasgeiter所建议的那样。 http://laravel.com/docs/4.2/eloquent#polymorphic-relations
我确实无法根据多态关系加载其他关系。例如,如果User
和Guest
都有相应的表格UserDetail
和GuestDetail
,那么我就无法获得热切的加载效果。所以我将其添加到User
和Guest
模型中:
protected $with = ['detail'];
这意味着每当customer
多态关系被加载时,User
和Guest
都会自动加载它们的关系。我想我也可以使用'延迟加载'功能$order->load('customer')
,但我没试过。
public function detail()
{
return $this->hasOne('UserDetail');
}
谢谢你们。