我正在为我的laravel应用程序构建分层的导航模块-就像在Magento或WooCommerce中一样。这就是想法:可以为产品分配单个或多个属性,然后用户应该可以使用这些属性过滤产品。就像属性“ Material ”一样,可以为产品分配一个或多个值,如铁,木材和塑料。我的问题是我不知道如何正确执行此操作。
我的数据模型是这样的:
products table: id | name | other info...
example: 42 | Chair | ...
example: 14 | Bike | ...
attributes table: id | name | description
example: 02 | Material | the material that the...
attribute_options table: id | attribute_id | value
example: 11 | 02 | Wood
example: 12 | 02 | Iron
pivot table: id | product_id | attribute_option_id
example: 12 | 42 | 11
example: 12 | 42 | 12
example: 12 | 14 | 12
我在产品模型和产品选项模型之间建立了多对多关系(因此有数据透视表)。
在我的 View 文件中,将显示一个表单,该表单循环所有不同的属性,然后循环其选项,并为每个选项创建一个复选框,并带有其ID的值。理想情况下,将这些值组合在一个数组中,并按以下方式命名: filter [attribute_id] [attribute_option_id] 。一个例子:
<input type="checkbox" name="filter[02][11]" value="id"> Wood
<input type="checkbox" name="filter[02][12]" value="id"> Iron
<input type="checkbox" name="filter[xx][xx]" value="id"> Etc..
提交表单后,所有选定的属性选项值都将发送到服务器,该路由应在该路径上处理此信息,并且仅返回满足所有不同条件的产品。
因此,如果将发布过滤器[02] [11]和[02] [12],则仅应返回分配了“木头”和“铁”属性选项的产品。
起初,我认为这很简单,但是我认为我不如我想的那样熟练。由于这是Laravel的问题,我很想提供一个 Eloquent 样式解决方案!
P.S.如果我搞砸了(我的思想背后的)数据模型,请告诉我!我仍在学习有关Web开发的许多知识,也许有更好,更清洁的解决方案/方法可以解决我的问题
--------编辑/其他信息--------
使用以下代码,我可以过滤一个属性
$products = $products->whereHas('attributeOptions', function($query)
{
$query->where(function($query)
{
$query->where('value', 'iron');
});
});
但是由于产品可以具有不同类型的多个属性(例如颜色和 Material 或多种 Material ),所以我需要能够设置多个这样的位置:
$products = $products->whereHas('attributeOptions', function($query)
{
$query->where(function($query)
{
$query->where('value', 'iron');
$query->where('value', 'wood');
$query->where('value', 'yellow');
});
});
但是此代码不起作用,因为它检查具有多个值的一行,而不是检查具有相同product_id的多行上的值。
产品和 attribute_options 之间的关系为:
public function attributeOptions() {
return $this->belongsToMany('AttributeOption', 'products_attribute_options', 'product_id', 'attribute_option_id');
}
这在 Eloquent /拉威尔中甚至可行吗,还是我需要一个不同的解决方案?
在此先感谢您,我很乐意向您学习!
最佳答案
我完全同意@astro和@Dave的评论。您应该重新考虑数据库设计。我将在此处重新发布@Dave的两个链接,以使它们对其他用户更具可见性:
How to implement filter system in SQL?
What is best performance for Retrieving MySQL EAV results as Relational Table
尽管从性能(具有许多属性和产品)的角度来看,这并不奏效,但以下是一种可以与您当前的设置一起使用的解决方案:
将您的复选框更改为此:
<input type="checkbox" name="filter[02][]" value="11"> Wood
<input type="checkbox" name="filter[02][]" value="12"> Iron
<input type="checkbox" name="filter[xx][]" value="xx"> Etc..
这样,同一过滤器的多个值将作为数字数组添加到
filter[02][]
$query = Product::query();
foreach(Input::get('filter') as $attributeId => $optionIds){
foreach($optionIds as $optionId){
$query->whereHas('attributeOptions', function($q) use ($attributeId, $optionId){
$q->where('attributeId', $attributeId)
->where('attribute_option_id', $optionId);
}
}
}
$products = $query->get();
关于php - Laravel:在多个值上过滤多对多,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28160607/