我和Laravel一起工作并陷入困境。我有以下模型:
CategoryProduct
包含哪些产品属于哪个类别(产品可能属于多个类别)的信息。
现在,当我想加载属于特定类别的所有产品时,我需要在Product
和CategoryProduct
上运行查询,这是我遇到的问题。
我给了它以下尝试,但没有成功:
$products = Product::where('status', '=', 'active')
->where('category_id', '=', $category_id)
->take($count)
->skip($skip)
->get();
显然,它会说category_id
不是专栏。
这是我的DB&模型结构:
ID, 名称, 等
ID, 名称, SKU, 等
ID, product_id,(Product.id的外键) category_id,(Category.id的外键) 等
class Product extends Eloquent {
protected $table = 'products';
protected $hidden = array();
public static $rules = array('name' => 'required|min:3');
}
类别模型
class Category extends Eloquent {
protected $table = 'categories';
public static $rules = array('name' => 'required|min:3');
}
CategoryProduct模型
<?php
class CategoryProduct extends Eloquent {
protected $table = 'category_products';
public function product()
{
return $this->belongsTo('Product');
}
public function category()
{
return $this->belongsTo('Category');
}
}
有关此问题的新问题
我正在尝试展示产品。如果未传递类别(值为-1),那么我将显示所有产品,否则我将显示已传递类别的产品。
现在,当我展示所有产品时,这些产品可能已经存在于一个类别中。我想显示已经在某个类别中的产品的勾选复选框。我正在做这样的事情:
if($category_id==-1)
$products = Product::where('status', '=', 'active')->take($count)->skip($skip)->get();
else{
$products = Product::whereHas('categories', function($q) use ($category_id)
{
$q->where('category_id', $category_id);
})->where('status', 'active')
->take($count)
->skip($skip)
->get();
}
表 category_products 将product_id,category_id作为列。
现在,查询:
$ products = Product :: where('status','=','active') - &gt; take($ count) - &gt; skip($ skip) - &gt; get();
只会从产品表中挑选产品。如果我在 category_products 中检查每个产品是否存在,那么对于大量产品将会有太多的数据库查询。
任何想法,如何实现这一目标。我希望我能够清除我的情况。感谢
答案 0 :(得分:3)
除非您有除product_id和category_id之外的其他字段指向其他关系,否则不应该CategoryProduct
模型。
在Category
和Product
模型上设置关系的方法是必要的。
在Category
中,添加关系函数...
public function products()
{
return $this->belongsToMany('Product', 'category_products');
}
在Product
模型中,对类别执行相同操作。
public function categories()
{
return $this->belongsToMany('Category', 'category_products');
}
然后,您可以使用关系方法和whereHas()
$products = Product::whereHas('categories', function($q) use ($category_id)
{
$q->where('id', $category_id);
})->where('status', 'active')
->take($count)
->skip($skip)
->get();
答案 1 :(得分:1)
在多对多关系中,您不需要透视表的模型。查看Eloquent文档的this section以获得进一步说明。
您仍需要创建迁移以设置数据透视表(如果不使用迁移,则需要手动执行),而不是模型。相反,为Category
创建一个函数来指定关系:
public function products()
{
return $this->belongsToMany('App\Product', 'category_products');
// - You might need to adjust the namespace of App\Product
// - category_products refers to the pivot table name
}
同样,Product
需要类似的公共功能。
然后你可以通过查找类别然后列出其所有相关产品来反过来做到这一点:
$products = Category::find($category_id)
->products()
->where('status', 'active')
->take($count)
->skip($skip)
->get();
This question也可能与您的相关。