Laravel Eloquent 嵌套查询
Laravel Eloquent nested query
我在与 Laravel 一起工作时陷入困境。我有以下型号:
- 类别
- 产品
- 类别产品
CategoryProduct
保存了哪个产品属于哪个类别的信息(一个产品可能属于多个类别)。
现在,当我想加载属于特定类别的所有产品时,我需要 运行 查询 Product
和 CategoryProduct
,这就是我遇到的问题。
我尝试了以下但没有成功:
$products = Product::where('status', '=', 'active')
->where('category_id', '=', $category_id)
->take($count)
->skip($skip)
->get();
很明显,它会说category_id
不是一个列。
这是我的数据库和模型结构:
类别table
id,
姓名,
等等
产品table
id,
姓名,
存货,
等等
category_products table
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');
}
类别产品型号
<?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();
}
table category_products 有 product_id, category_id 列。
现在,查询:
$products = Product::where('status', '=', 'active')->take($count)->skip($skip)->get();
将仅从 products table 中挑选产品。如果我检查每个产品在 category_products 中是否存在,那么大量产品的数据库查询就会太多。
任何想法,如何实现这一目标。我希望我能够清除我的情况。谢谢
CategoryProduct
模型不是必需的,除非除了 product_id 和 category_id 之外还有指向其他关系的其他字段。
需要的是在 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();
您不需要多对多关系中的枢轴模型 table。查看 Eloquent 文档的 this section 以获得进一步的解释。
您仍然需要创建一个迁移来设置数据透视表 table(或者如果您不使用迁移则手动执行),但不是模型。相反,为 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
需要类似的 public 功能。
然后您可以反过来,找到类别,然后列出所有相关产品:
$products = Category::find($category_id)
->products()
->where('status', 'active')
->take($count)
->skip($skip)
->get();
This question 也可能与您的相关。
我在与 Laravel 一起工作时陷入困境。我有以下型号:
- 类别
- 产品
- 类别产品
CategoryProduct
保存了哪个产品属于哪个类别的信息(一个产品可能属于多个类别)。
现在,当我想加载属于特定类别的所有产品时,我需要 运行 查询 Product
和 CategoryProduct
,这就是我遇到的问题。
我尝试了以下但没有成功:
$products = Product::where('status', '=', 'active')
->where('category_id', '=', $category_id)
->take($count)
->skip($skip)
->get();
很明显,它会说category_id
不是一个列。
这是我的数据库和模型结构:
类别table
id, 姓名, 等等
产品table
id, 姓名, 存货, 等等
category_products table
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');
}
类别产品型号
<?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();
}
table category_products 有 product_id, category_id 列。
现在,查询:
$products = Product::where('status', '=', 'active')->take($count)->skip($skip)->get();
将仅从 products table 中挑选产品。如果我检查每个产品在 category_products 中是否存在,那么大量产品的数据库查询就会太多。
任何想法,如何实现这一目标。我希望我能够清除我的情况。谢谢
CategoryProduct
模型不是必需的,除非除了 product_id 和 category_id 之外还有指向其他关系的其他字段。
需要的是在 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();
您不需要多对多关系中的枢轴模型 table。查看 Eloquent 文档的 this section 以获得进一步的解释。
您仍然需要创建一个迁移来设置数据透视表 table(或者如果您不使用迁移则手动执行),但不是模型。相反,为 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
需要类似的 public 功能。
然后您可以反过来,找到类别,然后列出所有相关产品:
$products = Category::find($category_id)
->products()
->where('status', 'active')
->take($count)
->skip($skip)
->get();
This question 也可能与您的相关。