2015-07-13 74 views
2

我正在做一個房地產相關的應用程序,我一直在很難搞清楚如何設置查詢,以便它會返回「Only Apartments or選定區域內的雙層住宅「我希望用戶能夠在城市的多個選定的象限中找到多種類型的住宅。Laravel雄辯:如何篩選多個和/或標準單表

我有一個列「類型」,它可以是「公寓」的數據庫,「家」,「雙面」,「移動設備」

在另一列我與值quadrant_main:「NW」,「 SW「,」NE「,」SE「。

我的代碼在只選擇了一個象限的情況下工作,但是當我選擇多個象限時,我似乎得到的結果包含所有第二或第三或第四象限的屬性類型,而不是僅「公寓」和「 Duplex「或任何類型的用戶選擇...任何幫助將不勝感激! thx提前。

我的控制器功能如下:

public function quadrants() 
{ 
    $input = \Request::all(); 
    $currentPage = null; 
    $column = "price"; 
    $order = "desc"; 

    // 
    // Looks like the input is like 0 => { key: value } ... 
    // (an Array of key/value pairs) 

    $q = Listing::where('status','=','Active')->where(function($query) { 
     $input = \Request::all(); 
     $currentPage = null; 
     $typeCount = 0; 
     $quadrantCount = 0; 

     foreach($input as $index => $object) { 

      $tempObj = json_decode($object); 
      $key = key((array)$tempObj); 
      $val = current((array)$tempObj); 

      if ($key == "type") { 
       if ($typeCount > 0) { 
        $query->orWhere('type', '=', $val); 
       } 
       else { 
        $query->where('type', '=', $val); 
        $typeCount++; 
       } 
      } 
      if ($key == "quadrant_main") { 
       if ($quadrantCount > 0) { 
        $query->orWhere('quadrant_main', '=', $val); 
       } 
       else { 
        $query->where('quadrant_main', '=', $val); 
        $quadrantCount++; 
       } 
      } 
      // else { 
      // $query->orWhere($key,$val); 
      // } 
     } 

     if($currentPage) { 
      //Force Current Page to Page of Val 
      Paginator::currentPageResolver(function() use ($currentPage) { 
       return $currentPage; 
      }); 
     } 
    }); 

    $listings = $q->paginate(10); 

    return $listings; 

回答

1

你的問題來看,它是一個有點混亂,沒有多少給予肯定回答。麻煩的可能原因可能是數據庫中的數據不正確,或者可能是用戶輸入錯誤。

免責聲明:請注意,我的答案根本不適用於您。 在這種情況下,請提供更多的信息,我們將的東西。

有一件事,我認爲你已經忽略了,因此你得到錯誤的結果。首先讓我假設一些事情。

我想一個樣本用戶輸入應該是這樣的:

array(
    0: '{type: Apartment}', 
    1: '{type: Duplex}', 
    2: '{quadrant_main: NW}', 
    3: '{quadrant_main: SW}', 
) 

什麼用戶的意思是讓我屬於西北或西南地區任何公寓或複式。

所以經過你的循環已經結束,最終的SQL語句應該是這樣的:

哦,而我們則是在SQL話題,您也可以登錄laravel實際 生成的SQL查詢,以便您實際上可以看到最終SQL生成的結果是什麼。如果你可以在這裏發佈,它會幫助 很多。 Look here.

select * from listings where status = 'Active' and (type = 'Apartment' or type = 'Duplex' and quadrant_main = 'NW' or quadrant_main = 'SW'); 

什麼這個查詢將實際產生的是:

Select any listing which is active and: 
1. Type is an apartment, or, 
2. Type is a duplex, or, 
3. Quadrant is SW, and, 
4. Quadrant is NW 

所以假設你有一個這樣的數據庫:

id|type|quadrant_main 
===================== 
1|Apartment|NW 
2|Apartment|SW 
3|Apartment|NE 
4|Apartment|SE 
5|Duplex|NW 
6|Duplex|SW 
7|Duplex|NE 
8|Duplex|SE 
9|House|NW 
10|House|SW 
11|House|NE 
12|House|SE 

您只能在結果收到1, and 5組。該結果集顯然是錯誤的,加上它取決於NW,因爲那是and條件。

正確的SQL查詢將是:

select * from listings where status = 'Active' and (type = 'Apartment' or type = 'Duplex') and (quadrant_main = 'NW' or quadrant_main = 'SW'); 

所以構建你的應用L5,使得生產這種SQL查詢。不要試圖在一個循環中塞入所有東西,而要有兩個循環。一個循環只能處理type,另一個循環只能處理quadrant_main。這樣你就可以在正確的位置獲得必要的and條件。


作爲附帶說明:

  1. 決不直接使用用戶輸入。一定要先清理它。
  2. 它不是將所有邏輯放入控制器的最佳實踐。使用存儲庫模式。 See here.
  3. 倍數where子句通常通過Criteria應用。檢查一下上面鏈接的存儲庫模式。
  4. 您的代碼邏輯非常複雜,完全沒有必要。不用發送JSON對象,只需發送複選框的狀態即可。不要嘗試通過循環進行泛化。取而代之的是逐個處理所有複選框,即選擇「公寓」,如果是,則將其添加到您的子句中,如果沒有,則不要添加。