Sie ein Modell Accessor dynamisches Feld nicht Abfrage begrenzen können, um die Datenbank zu verwenden, da das Feld in der Datenbank nicht offensichtlich vorhanden.
Das Collection-Objekt verfügt jedoch über ziemlich robuste Filterfunktionen, sodass Sie die Erfassungsergebnisse mithilfe der dynamischen Felder filtern können, nachdem die Datenbank abgefragt wurde. Dies ist nicht so leistungsfähig wie das Herausfiltern der Ergebnisse, bevor sie aus der Datenbank abgerufen werden, aber Sie können eine Situation sein, in der die Leistung nicht so kritisch ist oder die Kosten für Sauberkeit/Wartung die Kosten überwiegen.
Als Beispiel gegeben folgendes Modell:
class Book extends Model
{
public function getCategoryAttribute()
{
if ($this->targetAge < 13) {
return 'child';
}
if ($this->targetAge < 18) {
return 'teen';
}
return 'adult';
}
}
Die folgende Abfrage wird nicht funktionieren, weil das category
Feld tatsächlich nicht in der Tabelle vorhanden:
$childrenBooks = Book::where('category', 'child')->get(); // error: no category field
jedoch die folgende wird funktionieren, weil Sie where()
für die Sammlung von Modellen aufrufen, die von der Datenbank zurückgegeben werden, und die Modelle haben Zugriff auf das dynamische Feld:
Das Problem in diesem Fall ist, dass, während es funktioniert, wird es alle Bücher aus der Datenbank und erstellen Sie eine Model-Instanz für jeden, und dann filtern Sie durch diese vollständige Sammlung. Der Vorteil besteht jedoch darin, dass Sie die Logik in Ihrer Zugriffsmethode nicht duplizieren müssen. Hier müssen Sie die Vor- und Nachteile abwägen und feststellen, ob dies in Ihrer Situation akzeptabel ist.
Eine Zwischen Möglichkeit wäre, ein Modell Anwendungsbereich Methode zu erstellen, so dass Ihre Zugriffslogik nur an einer Stelle dupliziert wird (wenn es für eine Abfrage kopiert werden kann):
class Book extends Model
{
public function getCategoryAttribute()
{
if ($this->targetAge < 13) {
return 'child';
}
if ($this->targetAge < 18) {
return 'teen';
}
return 'adult';
}
public function scopeCategory($query, $category)
{
if ($category == 'child') {
return $query->where('target_age', '<', 13);
}
if ($category == 'teen') {
return $query->where(function ($query) {
return $query
->where('target_age', '>=', 13)
->where('target_age', '<', 18);
});
}
return $query->where('target_age', '>=', 18);
}
}
Dann können Sie diese verwenden Abfragebereich wie folgt:
$childrenBooks = Book::category('child')->get();
der Vorteil hierbei ist, dass die Logik auf die eigentliche Abfrage gilt, so werden die Datensätze beschränkt, bevor sie aus der Datenbank zurückgegeben werden. Das Hauptproblem besteht nun darin, dass Ihre "Kategorie" -Logik verdoppelt wird, einmal in einem Accessor und einmal in einem Bereich. Darüber hinaus funktioniert das nur, wenn Sie Ihre Accessor-Logik in etwas verwandeln können, das von einer Datenbankabfrage behandelt werden kann.
Aber ich möchte meine Abfrage-Ergebnis auf die temporäre Tabelle setzen, ist es möglich? –
Ja, ich sehe nicht warum nicht, ähnlich wie eine SQLite-Verbindung im Speicher, die Daten sind alle dort unter der Verbindung schließt. – btl