2017-12-13 4 views
0

ich eine Suchanfrage wie diese:Laravel - vorbei Array von Spalten in ‚where‘ -Klausel

$data = User::where('first_name', 'like', '%'.$query.'%') 
    ->orWhere('last_name', 'like', '%'.$query.'%') 
    ->get(); 

Nun, ich habe viele Modelle, die jeweils mit unterschiedlichen Spaltennamen. Statt eine search() Funktion in jeden Controller definieren, möchte ich dies tun:

// User 
public static function searchableFields() 
{ 
    return ['first_name', 'last_name']; 
} 

// Some other model 
public static function searchableFields() 
{ 
    return ['name', 'description']; 
} 

Und legen Sie die Suchlogik in einem gemeinsamen Controller, etwa wie folgt:

$data = $classname:: 
    where($classname::searchableFields(), 'like', '%'.$query.'%') 
    ->get(); 

Wie kann ich das erreichen?

Vielen Dank.

+0

In der Regel können Spaltennamen keine Parameter in der Abfrage sein, nicht ohne dynamisches SQL. Warum sind einige Spalten ein Problem für Sie? –

Antwort

1

können Sie Schleife über die Felder und fügen Sie sie in Ihre Eloquent Abfrage eins nach dem anderen.

$data = $classname::where(function ($query) use ($classname) { 
    foreach ($classname::searchableFields() as $field) 
     $query->orWhere($field, 'like', '%' . $query . '%'); 
})->get(); 
+0

Danke Jerodev! Genau das habe ich gesucht. Es wirkt wie ein Zauber! – Oscar

+0

Ich bin froh, dass ich helfen konnte. Erwägen Sie, dies als Lösung für Ihre Frage zu markieren, damit auch andere Benutzer diese finden können. – Jerodev

+0

@Oscar dann markieren Sie es als beantwortet –

0

Sie können so etwas versuchen.

// Controller-

function getIndex(Request $request) 
{ 
    $this->data['users'] = User::orderBy('first_name','asc')->get(); 

    if ($request->has('keyword')) { 
     $results    = User::search($request->keyword); 
     $this->data['users'] = collect([$results])->collapse()->sortBy('first_name'); 
    } 
} 

// Modell

function search($keyword) 
{ 
    $results  = []; 
    $search_list = ['first_name','last_name']; 
    foreach ($search_list as $value) 
    { 
     $search_data = User::where($value,'LIKE','%'.$keyword.'%')->get(); 
     foreach ($search_data as $search_value) { 
      $exist = 0; 
      if (count($results)) { 
       foreach ($results as $v) { 
        if ($search_value->id == $v->id) { 
         $exist++; 
        } 
       } 
       if ($exist == 0) { 
        $results[] = $search_value; 
       } 
      } else{ 
       $results[] = $search_value; 
      } 
     } 
    } 
    return $results; 
} 
+0

Aber das führt so viele Abfragen wie es Schlüsselwörter gibt und es hat viel unnötigen Code. – Jerodev

1

Ich würde Umfang dafür verwenden.

Sie können Basismodell erstellen, das alle Modelle erweitern sollte (und das Modell sollte Eloquent Modell erweitern) und in diesem Modell sollten Sie solche Methode hinzufügen:

public function scopeMatchingSearch($query, $string) 
{ 
    $query->where(function($q) use ($string) { 
     foreach (static::searchableFields() as $field) { 
      $q->orWhere($field, 'LIKE', '%'.$string.'%'); 
     } 
    }); 
} 

Jetzt können Sie eine Suche wie folgt ein:

$data = User::matchingSearch($query)->get(); 

nur Verwirrung zu vermeiden - $query Parameter übergeben zu matchingSearch wird $string Parameter in dieser Methode.

+0

Hallo Marcin, das ist ein großartiger Ansatz und funktioniert gut. – Oscar