2017-10-19 14 views
4

私はいくつかの製品のフィルタに取り組んでいます。私はそれの大部分は動作していますが、不可能なwhere句でエラーに遭遇しています。Laravel impossible query

表には1つの製品の複数の行が含まれていますが、製品ごとに複数の基準を一致させようとしていますが、これは失敗につながります。

これについて意見がある場合、またはこれを修正する方法があれば、大変感謝します。

データベーステーブルは次のようになります。

 
    -------------------------------------------- 
    |id | FilterKey | filterValue | product_id | 
    -------------------------------------------- 
    |1 | Colour | Gunmetal | 1   | 
    |2 | Colour | Silver  | 1   | 
    |3 | Size  | 750cc  | 1   | 
    |4 | Size  | 1000cc  | 1   | 
    |5 | Colour | Red   | 2   | 
    |6 | Colour | Blue  | 2   | 
    |7 | Size  | 750cc  | 2   | 
    |8 | Size  | 1000cc  | 2   | 
    -------------------------------------------- 

とフィルタは次のようになります。その後、

public function scopeFilterProduct($query, $filters) 
{ 
    $this->filters = $filters; 
    if (count ($this->filters) === 1 && isset($this->filters[0])) 
    { 
     return $query; 
    } 
    $query->join('product_filters', 'products.id', '=', 'product_filters.product_id')->Where(function($query){ 
     foreach ($this->filters as $filter => $vals) 
     { 
      $this->filter = $filter; 
      $this->vals = $vals; 
      $query->Where(function ($query){ 

       $query->Where('filterKey', $this->filter); 

       $query->Where(function($query){ 
        foreach ($this->vals as $val){ 

         $query->orWhere('filterValue', $val); 
        } 
        $this->vals = null; 
       }); 

      }); 
      $this->filter = null; 
     }; 
    }); 
    return $query; 
} 

この次のSQL文を出力します

select 
    distinct 
    `products`.`id` 
    , `product_id` 
from 
`products` 
inner join 
`product_filters` 
on 
`products`.`id` = `product_filters`.`product_id` 
where 
    (
     (`filterKey` = 'Colour' and (`filterValue` = 'gunmetal')) 
     and 
     (`filterKey` = 'Size' and (`filterValue` = '750cc')) 
    ) 
    and 
     `products`.`deleted_at` is null 

このオプションを選択すると、スクリーンショットのように、「product one」のみがページに表示されます。

+0

これは、「製品を取得されて従って、セットdivision.Theロジックと呼ばれていることを" – apokryfos

答えて

0

あなたが私の意見で追加した範囲は間違っています。あなたのデータベース構造でさえ、私の意見では間違っています。ここで私はこれを構造化する方法を次のとおりです。

フィルタ表が

このモデルでは、すべてのフィルタ値を保持します。

----------------- 
|id | name  | 
----------------- 
|1 | Colour | 
|2 | Size  | 
----------------- 

だからあなたの雄弁なモデルがこのようなものになる::

class Filter extends Model 
{ 
    protected $fillable = ['id', 'name']; 

    public function products() 
    { 
     return $this->belongsToMany(Product::class, 'products_filters');   
    } 
} 

製品表

あなたの製品モデルたとえば、ここでColourSizeなどがフィルタテーブルを構造化する方法であります

class Product extends Model 
{ 
    public function filters() 
    { 
     return $this->belongsToMany(Filter::class, 'products_filters');   
    } 
} 

上記の変更後products_filters表

は、ここにテーブルが構造化される方法である。

-------------------------------------------- 
|id | filter_id | filterValue | product_id | 
-------------------------------------------- 
|1 | 1   | Gunmetal | 1   | 
|2 | 1   | Silver  | 1   | 
|3 | 2   | 750cc  | 1   | 
|4 | 2   | 1000cc  | 1   | 
|5 | 1   | Red   | 2   | 
|6 | 1   | Blue  | 2   | 
|7 | 2   | 750cc  | 2   | 
|8 | 2   | 1000cc  | 2   | 
-------------------------------------------- 

今、あなたは、単にすべてのフィルタの関連製品を取得し、その後、フィルタテーブルを照会することができます。その後、一意の製品のリストをコンパイルするだけです。

選択したフィルタに基づくUnqiue製品。あなたのビューで
$ids = []; 
$products = new \Illuminate\Support\Collection(); 

foreach($filters as $filter) { 
    foreach($filter->products as $product) { 
     if(!in_array($product->id, $ids)) { 
      $ids[] = $product->id; 
      $products->push($product); 
     } 
    } 
} 

return view('results', compact('products')); 

は、次のように記述する必要があります:選択したフィルタが存在しないため

@foreach($products as $product) 
// Your product block HTML 
@endforeach 
+0

Razaさんありがとうございます、私は今これを援助することを検討しています。これで解決します。 2つのフィルタに一致する製品を引き出すことをどのように考えていますか? –

+0

提供された製品フィルタに基づいてユニークな商品をどのようにフィルタリングするかを記述する私の答えを更新しました。 –