2016-03-18 15 views
0

Ich versuche, Daten über Eloquent in einer Methode zu filtern, die nur auf AJAX-Anforderungen antwortet und dann die Ansicht zusammen mit den gefilterten Daten zurückgibt. Allerdings habe ich eine Frage:Verwenden eloquent beim Filtern von Daten ohne Redundanz

Zuerst lässt einen Blick auf meinen Code nehmen:

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()); 

    } 
} 

Dies ist der einzige Weg war, konnte ich es tun, es funktioniert, aber ich fühle mich wie es nicht der beste Weg ist Um dies zu tun, besonders wenn Sie mehr Felder zu filtern haben, würde der Code enorme Proportionen mit den Überprüfungen nehmen, gibt es einen besten Weg, dies zu tun?

Zum Beispiel Erstellen der Abfrage während der Überprüfung und dann am Ende ausführen?

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

// Execute query and get the results 

Antwort

1

Meiner Meinung nach, könnte Ihr Code wie so vereinfacht werden:

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()); 
    } 
} 

ich für einige Projekte in meinem Unternehmen diese Methode verwendet haben, und alles funktioniert prima. Versuch es einmal.

+0

Vielen Dank Sir, das ist, was ich gesucht habe. Viel einfacher. –

+0

Glücklich, Ihnen zu helfen. Vereinfachter und effizienter natürlich. Einen schönen Tag noch. –

0

Ich bin nicht sicher, dass es unbedingt ein bester Weg, dies zu tun, wenn man bedenkt, was Sie in Ihrem ursprünglichen Code erzeugt sieht für mich völlig in Ordnung, aber es gibt sicherlich Möglichkeiten. Wenn Sie WHERE-Klauseln verwenden, die Sie beispielsweise regelmäßig verwenden, können Sie Bereiche verwenden, um Gebäudebedingungen zu zentralisieren, die darauf abzielen, ein bestimmtes Ergebnis zu erzielen, und diese nach Bedarf stapeln. Dies ermöglicht Ihnen die Flexibilität, in der Zukunft einen Platz im Code zu ändern und alle anderen Orte zu beeinflussen, an denen der aktualisierte Bereich verwendet wurde, falls Ihre Bedingung geändert werden muss. Aber das mag mehr mit größeren Problemen der Code-Wartbarkeit zu tun haben, als Sie vielleicht in diesem speziellen Fall suchen.

Persönlich habe ich Ihre hypothetische Methode ziemlich oft verwendet. Es funktioniert gut für mich, wenn ich einen API-Endpunkt für eine Ressource habe, die filterbar ist, und die Filter können variabel sein. Suchen Sie nach Benutzern nach einer beliebigen Kombination aus Vorname, Nachname und/oder E-Mail.

Hier ist, was das für mich wie folgt aussieht:

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 
} 

Das finde ich eine gute Konvention für ein paar Gründe zu sein. Erstens finde ich den Code sehr gut lesbar sein, da jeder Block auf Selbst Dokument tendiert dazu, sich gut (wenn die AnfragehatE-Mail ...). Zweitens kann ich jeden Block, der in Zukunft entfernt werden muss, schnell und einfach entfernen, ohne etwas abwickeln zu müssen.

Eine große Einschränkung dieses Ansatzes ist, dass jeder Filter unabhängig von den anderen wirkt - wählen Sie 0 oder mehr Filter in beliebiger Kombination. Es wird ein wenig komplizierter, wenn Sie sich in einer Situation befinden, in der Sie nach Kombinationen von Gruppen filtern können. Selbst dort können Sie die Kombinationen in der Regel in ihre eigenen Blöcke trennen und ungefähr dasselbe erreichen.

Also noch einmal, ich denke, was Sie aus dem ersten Teil Ihrer Frage haben, ist absolut gültig, aber würde den Code aus dem zweiten Teil der Frage als eine sauberere und wartungsfreundlichere Option vorschlagen.