2017-11-08 15 views
0

나는이 쿼리를 생성하는 다음 쿼리 빌더를 한 : 최소 및 최대 가격 필터링을 사용하는 경우Laravel의 웅변은

내 문제는 판매 및 스톡 옵션에 WHERE 조건 내에 자리 잡고 있습니다. 내 URL은 다음과 같습니다

category/men-clothes?sale=no_sale&min_price=10&max_price=10000&per_page=8 

판매 = no_sale이 쿼리는 '='의 경우 'SALE_PRICE'을 수행하는 것을 의미, 0, 따라서이 내 SQL 쿼리 :

and `sale_price` = ? order by `id` desc 

을하지만, 그것을 여전히 sales_price가 0보다 큰 제품을 가져 오지만, on_sale로 전환하면 0보다 큰 sale_price가있는 제품 만 가져옵니다. 따라서 문제는 적극적인 판매가없는 제품을 선택할 때뿐입니다. 그래서 on_stock과 no_stock에 대한 정보를 얻을 수 있습니다. 여기서는 올바른 제품을 가져 오지 않습니다. 나는 제작자가 꽤 크다는 것을 알고 있지만, 왜 제대로 작동하지 않는지를 설명 할 수 없었다. 그것은 완전히 제대로 필터링 된 min_price 및 max_price를 제거한 후에 만 ​​작동합니다. 따라서 어딘가에 where 및 orWhere에 가격 문제가 발생합니다.

.

select * from `products` where exists (select * from `categories` inner join `product_categories` on `categories`.`id` = `product_categories`.`category_id` where `products`.`id` = `product_categories`.`product_id` and `id` = ?) and (`has_variants` = ? and `price` >= ?) or (`has_variants` = ? and `min_price` != ? and `min_price` >= ?) and (`has_variants` = ? and `price` <= ?) or (`has_variants` = ? and `max_price` != ? and `max_price` <= ?) and `sale_price` = ? order by `id` desc 

.

$products = Product::whereHas('categories', function ($query) use ($category) { 
      $query->where('id', '=', $category->id); 
     })->when(count($brand_list) > 0, function ($query) use ($brand_list) { 
      $query->whereHas('brand', function ($query) use ($brand_list) { 
       $query->whereIn('slug', $brand_list); 
      }); 
     })->when($minPrice, function ($query) use ($data) { 
      $query->where([ 
        ['has_variants', '=', 0], 
        ['price', '>=', $data['active_filters']['min_price']], 
       ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['min_price', '!=', 0], 
        ['min_price', '>=', $data['active_filters']['min_price']], 
       ]); 
     })->when($maxPrice, function ($query) use ($data) { 
      $query->where([ 
       ['has_variants', '=', 0], 
       ['price', '<=', $data['active_filters']['max_price']], 
      ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['max_price', '!=', 0], 
        ['max_price', '<=', $data['active_filters']['max_price']], 
       ]); 
     })->when($orderPrice, function ($query) use ($orderPrice) { 
      $query->orderBy('price', $orderPrice); 
     })->when(!$orderPrice, function ($query) { 
      $query->orderBy('id', 'desc'); 
     })->when($stockOrder, function ($query) use ($stockOrder) { 
      if($stockOrder == 'in_stock') { 
       $query->where('quantity', '>', 0); 
      } else if($stockOrder == 'no_stock') { 
       $query->where('quantity', '=', 0); 
      } 
     })->when($saleOrder, function ($query) use ($saleOrder) { 
      if($saleOrder == 'on_sale') { 
       $now = time(); 
       $query->where([ 
        ['sale_price', '>', 0], 
        ['sale_start', '<', $now], 
        ['sale_end', '>', $now], 
       ])->orWhere([ 
        ['sale_price', '>', 0], 
        ['sale_start', '=', 0], 
        ['sale_end', '=', 0], 
       ]); 
      } else if($saleOrder == 'no_sale') { 
       $query->where('sale_price', '=', 0); 
      } 
     })->when($featuredOrder, function ($query) use ($featuredOrder) { 
      if($featuredOrder == 'featured') { 
       $query->where('featured', '=', 1); 
      } else if($featuredOrder == 'not_featured') { 
       $query->where('featured', '=', 0); 
      } 
     })->when(count($activeColors) > 0, function ($query) use ($activeColors) { 
      $query->whereHas('colors', function ($query) use ($activeColors) { 
       $query->whereIn('value', $activeColors); 
      }); 
     })->when(count($activeSizes) > 0, function ($query) use ($activeSizes) { 
      $query->whereHas('sizes', function ($query) use ($activeSizes) { 
       $query->whereIn('value', $activeSizes); 
      }); 
     })->with(['colors', 'sizes', 'reviewsCount'])->get(); 

답변

1

여기 문제는 orWhere입니다. 언제 어디서나 사용하거나 추가 클로저로 항상 포장해야합니다. 이제 살펴 보자 :

->when($minPrice, function ($query) use ($data) { 
      $query->where([ 
        ['has_variants', '=', 0], 
        ['price', '>=', $data['active_filters']['min_price']], 
       ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['min_price', '!=', 0], 
        ['min_price', '>=', $data['active_filters']['min_price']], 
       ]); 
     }) 

이 부분은 아마 다음과 같아야합니다

->when($minPrice, function ($query) use ($data) { 
     $query->where(function($query) use ($data) { 
      $query->where([ 
        ['has_variants', '=', 0], 
        ['price', '>=', $data['active_filters']['min_price']], 
       ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['min_price', '!=', 0], 
        ['min_price', '>=', $data['active_filters']['min_price']], 
       ]); 
      }); 
     }) 

당신이 전체 where .. orWhere보다시피

추가 폐쇄에 싸여 있었다.

이유는 분명합니다. 당신이 클로저를 사용할 때 그래서 그들은 있도록 쿼리 추가 괄호를 추가합니다

WHERE A and (B or C) and (D or E) 

: 추가 폐쇄가없는 경우이

WHERE A and B or C and D or E 

같은 쿼리를 생성 할 수 있으며, 보통은 다음과 같이해야한다 그것은 작동합니다.

당신은 분명 당신이

+0

네, 덕분에 예상대로 작동하도록 모든 사람에게 where ... orWhere 구성을 마무리해야하는 같은 방법으로. 나는 어디에 (서) 그들을 묶을 여분의 것으로 나의 모든 절을 싸야 만했다. 정말 고맙습니다! 그것은 지금 매력처럼 작동합니다. –