Laravel 4 Project,使用Eloquent ORM。
我有三个表:客户,订单和产品(+ 1个数据透视表order_product)。客户与订单一对多关联。订单与产品多对多关联。
Customers 1-->N Orders N<-->N Products
我想在Customer模型上有一个方法来检索客户正在购买的产品列表。
为了更好地理解这一点,假设产品是消耗品。
例如,客户#1可以放置:
...我想要检索的结果是带有产品A,B,C,D和E的集合。
模型(动态伪编码):
class Product extends Eloquent {
public function orders()
{
return $this->belongsToMany('Order');
}
}
class Orders extends Eloquent {
public function customer()
{
return $this->belongsTo('Customer', 'customer_id');
}
public function products()
{
return $this->belongsToMany('Product');
}
}
class Customers extends Eloquent {
public function orders()
{
return $this->hasMany('Orders', 'customer_id');
}
public function products()
{
// What to put here ???
}
}
答案 0 :(得分:3)
感谢@ deczo的回答,我能够提出一个查询方法来检索项目:
public function items()
{
$query = DB::table('items')->select('items.*')
->join('item_order', 'item_order.component_id', '=', 'items.id')
->leftJoin('orders', 'item_order.order_id', '=', 'orders.id')
->leftJoin('customers', 'customers.id' , '=', 'orders.customer_id')
->where('customers.id', $this->id)
->distinct()
->orderBy('items.id');
$eloquent = new Illuminate\Database\Eloquent\Builder( $query );
$eloquent->setModel( new Item );
return $eloquent->get();
}
答案 1 :(得分:3)
这是多对多关系,但订单表作为数据透视表。
class Customers extends Eloquent {
public function orders()
{
return $this->hasMany('Orders', 'customer_id');
}
public function products()
{
return $this->belongsToMany('Products', 'orders', 'customer_id', 'product_id');
}
}
我已经包含了最后两个参数,但是如果您遵循singular_id模式,则可以将它们排除在外。
答案 2 :(得分:1)
我想不出这个简单的关系方法,但这是一个解决方法:
$productsIds = DB::table('customers')
->leftJoin('orders', 'orders.customer_id', '=', 'customers.id')
->join('order_item', 'order_item.order_id', '=', 'orders.id')
->leftJoin('items', 'order_item.item_id' , '=', 'items.id')
->distinct()
->get(['items.id']);
$productsIds = array_fetch($productsIds, 'id');
$productsCollection = Product::whereIn('id', $productsIds);
答案 3 :(得分:1)
@ deczo的答案可能工作得很好,并且可能性能更高,因为所有的数据缩减都是在数据库中完成的,但这里是一个纯粹的Laravel&#39;毫无疑问,这种方式更具可读性:
use Illuminate\Database\Eloquent\Collection;
class Customer extends Eloquent
{
...
public function products()
{
$products = new Collection;
foreach ($this->orders as $order) {
$products = $products->merge($order->products);
}
return $products;
}
}
请注意,此方法不会像普通关系方法一样 - 获取您调用方法的结果集合(即$products = $customer->products();
),并且您无法像关系一样将其作为属性访问(即你不能$products = $customer->products;
)。
另外,我在这里对Illuminate\Database\Eloquent\Collection#merge()
方法有所了解,它会自动执行DISTINCT
类似的事情。如果没有,您将不得不做$collection->unique()
类似的事情。