2016-12-08 3 views
0

Ich habe ein Problem mit Laravel 5.3 eifrig geladenen Beziehungen mit Methode mit().Laravel 5.3 eifrig geladene Beziehungen mit Methode mit()

Entweder mache ich etwas falsch, oder ich verstehe es falsch.

ich diesen Code ausführen:

 
$result = Post::with(['comments' => function ($query) { 

    $query->where('content', 'like', '"%blanditiisx%"'); 

}])->get(); 

Durch die Überprüfung empirisch Datenbanktabelle ‚Kommentare‘, ich weiß, dass es nur einzelner Kommentar ist das Wort ‚blanditiisx‘ in seiner Spalte ‚Inhalt‘ hat.

Also, da gegebene Kommentar kann nur zu einem Beitrag gehören und wir haben nur einen Kommentar passend 'where' Bedingung, ich wollte nur einen Beitrag zu bekommen.

Zu meiner Überraschung gibt der obige Code alle Beiträge zurück, die ich in der Datenbank habe.

Ich würde mich freuen, wenn mir jemand sagen könnte, wo ich falsch liege. Hier


ist das, was ich arbeite mit:


POST

Ich habe Beitrag Klasse mit dieser Beziehung darin definiert:

 
/** 
* One to Many relation 
* 
* @return \Illuminate\Database\Eloquent\Relations\hasMany 
*/ 
public function comments() 
{ 
    return $this->hasMany(Comment::class); 
} 

Es Arbeitet mit diesen Posts Tabelle:

 
+------------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+------------+------------------+------+-----+---------+----------------+ 
| id   | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| created_at | timestamp  | YES |  | NULL |    | 
| updated_at | timestamp  | YES |  | NULL |    | 
| title  | varchar(255)  | NO |  | NULL |    | 
| slug  | varchar(255)  | NO | UNI | NULL |    | 
| summary | text    | NO |  | NULL |    | 
| content | text    | NO |  | NULL |    | 
| seen  | tinyint(1)  | NO |  | 0  |    | 
| active  | tinyint(1)  | NO |  | 0  |    | 
| user_id | int(10) unsigned | NO | MUL | NULL |    | 
+------------+------------------+------+-----+---------+----------------+ 

KOMMENTAR

Ich habe Kommentar Klasse mit dieser Beziehung darin definiert:

 
/** 
* One to Many relation 
* 
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo 
*/ 
public function post() 
{ 
    return $this->belongsTo(Post::class); 
} 

es mit dieser Kommentar Tabelle funktioniert:

 
+------------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+------------+------------------+------+-----+---------+----------------+ 
| id   | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| created_at | timestamp  | YES |  | NULL |    | 
| updated_at | timestamp  | YES |  | NULL |    | 
| content | text    | NO |  | NULL |    | 
| seen  | tinyint(1)  | NO |  | 0  |    | 
| user_id | int(10) unsigned | NO | MUL | NULL |    | 
| post_id | int(10) unsigned | NO | MUL | NULL |    | 
| deleted_at | timestamp  | YES |  | NULL |    | 
+------------+------------------+------+-----+---------+----------------+ 

EDIT:

Eigentlich meine anfängliche Code funktioniert, es gibt nur Ergebnisse in einer Weise, die mich verwirrt bekam.

Was es tut ist, es gibt eine Sammlung für jeden Beitrag zurück.

Die meisten von ihnen sind leer. Nur die Auflistungen, die in die Abfragebeschränkungen fallen, werden mit Daten gefüllt.

Rest sind leer, aber immer noch abgerufen, um sie herauszufiltern, kann man count() verwenden.

Und natürlich sind sie eifrig.

Antwort

1

Sie können whereHas() versuchen, dies so:

$result = Post::whereHas('comments', function ($query) { 

    $query->where('content', 'like', '"%blanditiisx%"'); 

})->with('comments')->get(); 

Es ermöglicht Einschränkungen angepasst, um eine Beziehung Einschränkung, wie die Überprüfung der Inhalt eines Kommentars hinzufügen.

Oder versuchen Sie, wie:

Post::whereHas('comments', function ($query) { 
      $query->where('content', 'like', '"%blanditiisx%"'); 
     }) 
     ->with(['comments' => function ($query) { 
      $query->where('content', 'like', '"%blanditiisx%"'); 
     }]) 
     ->get(); 

Docs

+0

Ich weiß, hat()/WhereHas() funktioniert, aber wird das noch eifrig geladen werden? – Jeffz

+0

Nein, deshalb habe ich in der Abfrage 'mit ('Kommentare') 'hinzugefügt. Wenn Sie nur einen gefilterten Kommentar erhalten möchten, fügen Sie auch die 'where' Bedingungen hinzu. –

+1

Sie können die Kombination 'whereHas' und' with' verwenden, um das Ergebnis zu erhalten. –

0

Die mit() -Methode für Vorbelastung bezogene Daten, die Abfrage nicht Filtern Sie bereits haben. Sehen Sie sich die whereHas() -Methode für die Filterung an, nach der Sie suchen.

+0

Laut Laravel docs https://laravel.com/docs/5.3/eloquent-relationships#one-to-many, wenn Sie auf der Seite 'Constraining Eager Loads' finden, finden Sie ein ähnliches Beispiel mit Erklärung: "Manchmal Sie Vielleicht möchte ich eine Beziehung eifrig laden, aber auch zusätzliche Abfragebedingungen für die Eager-Lade-Abfrage angeben. "- so scheint es nahe liegend zu sein, dass es möglich sein sollte, Abfragen fein zu gestalten. – Jeffz

+0

Das beschränkt die "eager loading query". In Ihrem Beispiel bedeutet das, dass Sie festlegen müssen, welche Kommentare Sie laden möchten. Sie schienen zu erwarten, dass es einschränkt, welche Beiträge geladen werden. Dafür ist woHas(). –

+0

Ja, Sie haben Recht - danke. – Jeffz