2015-07-13 4 views
2

Я делаю приложение, связанное с недвижимостью, и мне было трудно определить, как настроить запрос, чтобы он возвращал «Только квартиры или Дуплексы в выбранных областях «Я хотел бы, чтобы пользователь мог находить несколько типов собственности в нескольких выбранных квадрантах города.Laravel Eloquent: как фильтровать несколько и/или критерии одной таблицы

У меня есть база данных с колонки «типа», который является либо «квартира», «Дом», «Дуплекс», «Мобильный»

В другой колонке я quadrant_main со значениями: «NW», " SW "," NE "," SE ".

Мой код работает, когда выбран только один квадрант, но когда я выбираю несколько квадрантов, я, кажется, получаю результаты, которые включают ВСЕ типы свойств со второго или третьего или четвертого квадранта, а не только «Квартира» и «Квартира», Дуплекс "или любые типы, которые пользователь выбирает ... Любая помощь будет оценена! 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 тему, вы можете также регистрировать фактическую генерируется SQL запрос в Laravel так что вы может реально увидеть, что был получен окончательный 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. Несколько предложений, где обычно применяются через Criteria. Проверьте это в приведенном выше шаблоне репозитория.
  4. Вы кодируете логику очень сложно и совершенно необязательно. Вместо отправки объектов JSON просто отправьте состояние флажков. Не пытайтесь обобщить функцию, перейдя в цикл. Вместо этого обрабатывайте все флажки один за другим, то есть выбрано «Апартаменты», если да, добавьте это в свое предложение, если нет, не добавляйте.
Смежные вопросы