我有一个复杂的关系,我试图在两个模型之间建立。
目标是使用$supplier->supply_orders
来访问用户提供商品的订单。
抛出:LogicException: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
。
使用我得到的代码我可以使用$supplier->supply_orders()->get()
,但是,当我尝试将其用作关系时,它会抛出。由于这是一种关系,我应该能够将它包含在一段关系中,但我该如何去做呢?
供应商型号:
class Supplier extends Model {
public function supply_orders() {
return Order::query()
->select('order.*')
->join('item_order', 'order.id', '=', 'item_order.order_id')
->join('item', 'item_order.item_id', '=', 'item.id')
->where('item.supplier_id', '=', $this->id);
}
}
~~~我认为你不需要的很多背信息可能会~~~
sql tables:
supplier
- id
items:
- id
- supplier_id
item_order:
- id
- order_id
- item_id
orders:
- id
其他雄辩模特:
class Item extends Model {
public function orders() {
return $this->belongsToMany('Order');
}
}
class Order extends Model {}
这应该如何运作的例子:
$supplier = factory(Supplier::class)->create();
$item = factory(Item::class)->create([
'supplier_id' => $supplier->id,
]);
$order = factory(Order::class)->create();
$order->items()->attach($item);
$orders = $supplier->supply_orders // Throws LogicException
抛出:LogicException: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
答案 0 :(得分:1)
听起来像是一个拥有多对多关系的hasManyThrough。 Laravel没有内置的支持,但你可以随时写下你自己的关系:https://laravel.io/forum/03-04-2014-hasmanythrough-with-many-to-many
如果你不想要人际关系,你总是可以这样做:
Order::whereHas('items.supplier', function($query) use($supplier) {
$query->where('id', $supplier->id);
});
为此,您需要在订单模型中使用关系函数items
,在商品模型中使用关系函数supplier
答案 1 :(得分:0)
我认为它引发关系错误的原因是你没有为
创建一个雄辩的关系$supplier->supply_orders.
相反,Laravel会将您的supply_orders()视为类中的方法,因此无法确定将哪个表用作数据透视表。要使基本关系在Eloquent中工作,您需要为供应商和订单之间的关系创建一个新的数据透视表,例如:
suppliers
-id
orders
-id
order_supplier
-id
-order_id
-supplier_id
从这里开始,Laravel将接受两者之间简单的多对多关系(这不会导致失败):
Supplier Class:
/**
* Get all orders associated with this supplier via order_supplier table
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function orders(){
return $this->belongsToMany("\App\Order");
}
既然供应商和订单之间的关系以及订单和物品之间的关系都很稳定,那么您可以急切地加载所有方向的关系。使用当前数据库设置使您的特定需求变得复杂的情况是,您有一个来自items表的第三个参数,它不是直接的枢轴。无需重新构建数据库,我认为最简单的方法是加载供应商和正常的关系:
$suppliers = Supplier::with('orders', function($query) {
$query->with('items');
});
从这里开始,你已经加载了所有的关系,并且可以在$ suppliers集合的后续内容中使用正确的item-> id来绘制这些关系。现在有很多方法可以让猫(甚至包括所有在一个查询中),因为你有Eloquent关系...但我倾向于通过将它分成几个可读的位来保持它更简单。
希望这有帮助。