2016-03-18 3 views
0

Я пытаюсь фильтровать данные через Eloquent в методе, который отвечает только на запросы AJAX, а затем возвращает представление вместе с отфильтрованными данными. Однако у меня есть вопрос:Использование красноречивого при фильтрации данных без избыточности

Во-первых, давайте посмотрим на мой код:

public function AJAX_get_reports(Request $request) 
{ 
    if($request->ajax()) 
    { 
     $message = $request->get('message'); 
     $severity = $request->get('severity'); 

     if(strlen($message) > 0 && strlen($severity) > 0) 
     { 
      $data = ServerReport::where('severity', '=', $severity)->where('message', '=', $message)->get(); 
     } elseif (strlen($message) > 0) { 
      $data = ServerReport::where('message', '=', $message)->get(); 
     } elseif (strlen($severity) > 0) { 
      $data = ServerReport::where('severity', '=', $severity)->get(); 
     } else { 
      $data = ServerReport::all(); 
     } 
     return Response::json(View::make('dashboard.reports.index', compact('data'))->render()); 

    } 
} 

Это был единственный способ, которым я был в состоянии сделать это, он работает, но я чувствую, что это не самый лучший способ для этого, особенно если у вас есть больше полей для фильтрации, код будет иметь огромное значение с проверками, есть ли лучший способ сделать это?

Например, построив запрос при выполнении проверок, а затем запустите его в конце?

if(strlen($message) > 0) 
{ 
    // add WHERE to query 
} 
if(strlen($severity) > 0) 
{ 
    // add WHERE to query 
} 

// Execute query and get the results 

ответ

1

На мой взгляд, ваш код может быть упрощена следующим образом:

public function AJAX_get_reports(Request $request) { 
    if($request->ajax()) { 
     $message = $request->get('message'); 
     $severity = $request->get('severity'); 
     $report = ServerReport::select('*'); //Initiate the variable for query container, change * to the columns that needs to be returned or just leave it 

     if (strlen($message) > 0) { 
      $report->where('message', '=', $message); //Add message filter 
     } 

     if (strlen($severity) > 0) { 
      $report->where('severity', '=', $severity); //Add severity filter 
     } 

     //Add another filters if needed 

     $data = $report->get(); //Get the data from either the filtered data or every single data without any filters 

     return Response::json(View::make('dashboard.reports.index', compact('data'))->render()); 
    } 
} 

Я использовал этот метод для некоторых проектов в моей компании, и все работает просто отлично. Дать ему шанс.

+0

Спасибо, сэр, это то, что я искал. Гораздо проще. –

+0

Рад помочь вам. Более упрощенный и более эффективный, конечно. Хорошего дня. –

0

Я не уверен, что обязательно есть лучший способ сделать это, учитывая, что вы производится в исходном коде выглядит отлично действует на меня, но есть, конечно, варианты. Если у вас есть предложения WHERE, которые вы используете регулярно, например, вы можете использовать области действия для централизации условных выражений здания, которые нацелены на достижение определенного результата, и складывать их по мере необходимости. Это позволяет вам гибко в будущем менять одно место в коде и воздействовать на все другие места, где использовалась обновленная область, в случае, если ваше состояние должно быть изменено. Но это может быть больше связано с большими проблемами ремонтопригодности кода, чем я думаю, что вы можете искать в этом конкретном случае.

Лично я использовал ваш гипотетический метод совсем немного. Он отлично работает для меня, когда у меня есть конечная точка API для ресурса, который можно фильтровать, и фильтры могут быть переменными. Например, поиск пользователей по любой комбинации имени, фамилии и/или электронной почты.

Вот как это выглядит для меня:

public function getIndex(Request $request, Response $response) 
{ 
    //Start with a copy of the model 
    //I prefer to instantiate the class from the container, 
    //instead of having it auto-injected using the method signature 
    //just personal preference 
    $users = app('App\User'); 

    //Filter by first name 
    if ($request->has('first_name')) { 
     $users->where('first_name', $request->input('first_name')); 
    } 

    //Filter by last name 
    if ($request->has('last_name')) { 
     $users->where('last_name', $request->input('last_name')); 
    } 

    //Filter by email 
    if ($request->has('email')) { 
     $users->where('email', $request->input('email')); 
    } 

    //If no conditions were set, get() *should* function like all() 
    $data = $users->get(); 

    //Do what you need with the data from here on out 
    //Typically I paginate the results for something like this 
} 

Я считаю, что это хорошая конвенция по нескольким причинам. Во-первых, я считаю, код быть очень удобным для чтения, так как каждый блок имеет тенденцию к самому себе-документ (а еслизапросимеетэлектронную почту ...). Во-вторых, я могу легко удалить любой блок, который нужно быстро и легко удалить в будущем, не отрывая ничего.

Одно из препятствий для этого подхода состоит в том, что каждый фильтр действует независимо от других - выбирайте 0 или более фильтров в любой комбинации. Это становится немного сложнее, если вы оказываетесь в ситуации, когда вы можете фильтровать комбинации групп. Даже там, хотя вы обычно можете разделить комбинации на свои собственные блоки и достичь примерно того же.

Итак, я думаю, что то, что у вас есть с первой части вашего вопроса, совершенно справедливо, но предложило бы код из второй части вопроса в качестве более чистого и удобного варианта.

Смежные вопросы