php - Laravel:对多个值进行多对多过滤

标签 php database laravel eloquent

我正在为我的 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    

我在ProductProduct Option 模型之间设置了多对多关系(因此有了数据透视表)。

在我的 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],则只应返回分配了“Wood”和“Iron”属性选项的产品。

起初,我认为这会很简单,但我认为我没有我想象的那么熟练......因为这是一个 Laravel 问题,我喜欢一个 Eloquent 风格解决方案!

附言如果我搞砸了(在我的背后思考)数据模型,请告诉我!我仍在学习很多关于 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 的多行的值。

productsattribute_options的关系是:

public function attributeOptions() {

    return $this->belongsToMany('AttributeOption', 'products_attribute_options', 'product_id', 'attribute_option_id');

}

这在 Eloquent/Laravel 中是否可行,或者我需要一个不同的解决方案

提前致谢,我很乐意向您学习!

最佳答案

我会通过使用 whereHas 方法来解决这个问题,然后使用 whereIn 来隔离包含所需属性的记录,然后将其过滤为仅包含具有正确数量属性的记录。

// Assuming you have the IDs of the attributes, rather than the value
$desiredAttributes = [11,12];
$products = $products->whereHas('attributeOptions', function($query)     
use($desiredAttributes)
{
    $query->whereIn('attribute_id', $desiredAttributes);
}, "=", count($desiredAttributes))->get();

所以这将首先获取所有具有属性 11 或 12 的记录,然后过滤到仅具有 count(attribute_option_id) == 2 的记录

关于php - Laravel:对多个值进行多对多过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28160607/

相关文章:

javascript - angular 2 服务不调用 php 文件

php - Out of memory (allocated 50855936) (试图分配 50331646 字节)

sql - 转换日期后只得到日期而不是时间

php - WhereNotExists Laravel Eloquent

PHP:空不适用于getter方法

java - SQLITE 数据库在 java 中被锁定(IDE NetBeans)

java - 在数据库中存储巨大的 HashMap

php - Laravel 5.1 队列中没有模型的查询结果

jquery - 使用 Laravel Carbon 将日期保存为 MySQL 格式

javascript - 注册表未正确处理到数据库(PHP/MySQL)