2016-12-15 3 views
2

Ich versuche herauszufinden, wie eifrig Daten aus einer verwandten Tabelle geladen werden. Ich habe 2 Modelle Group und GroupTextPost.Eloquent - Eager Loading Relationship

Group.php

<?php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class Group extends Model 
{ 
    protected $table = 'group'; 

    public function type() 
    { 
     return $this->hasOne('\App\Models\GroupType'); 
    } 

    public function user() 
    { 
     return $this->belongsTo('\App\Models\User'); 
    } 

    public function messages() 
    { 
     return $this->hasMany('\App\Models\GroupTextPost'); 
    } 
} 

GroupTextPost.php

<?php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class GroupTextPost extends Model 
{ 
    protected $table = 'group_text_post'; 

    public function user() 
    { 
     return $this->belongsTo('\App\Models\User'); 
    } 

    public function group() 
    { 
     return $this->belongsTo('\App\Models\Group'); 
    } 
} 

Was ich versuche ist eifrig Last zu tun, die user wenn das Abrufen Gruppe Text-Beiträge so, dass, wenn ich ziehen In den Nachrichten ist der Name des Benutzers enthalten.

Ich habe versucht, es wie so tun:

public function messages() 
{ 
    return $this->hasMany('\App\Models\GroupTextPost')->with('user'); 
} 

... und Aufruf wie folgt:

$group = Group::find($groupID); 
$group->messages[0]->firstname 

Aber ich erhalte eine Fehlermeldung:

Unhandled Exception: Call to undefined method Illuminate\Database\Query\Builder::firstname() 

Ist das möglich mit Beredtsam zu tun?

+1

Try verwenden '' '$ m = $ gruppen-> Nachrichten() -> get();' '' und dann '' '$ m [0] -> user [0] -> first_name;' '' – Dev

+0

Nachrichten haben den Vornamen oder den Benutzer haben? – Dev

+0

@Dev Benutzer hat den Vornamen. – BugHunterUK

Antwort

3

Sie sollten nicht unbedingt direkt auf die Beziehung laden. Sie könnten den Benutzer unbedingt immer auf das GroupTextPost-Modell laden.

GroupTextPost.php

<?php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class GroupTextPost extends Model 
{ 
    protected $table = 'group_text_post'; 

    /** 
    * The relations to eager load on every query. 
    * 
    * @var array 
    */ 
    protected $with = ['user']; 

    public function user() 
    { 
     return $this->belongsTo('\App\Models\User'); 
    } 

    public function group() 
    { 
     return $this->belongsTo('\App\Models\Group'); 
    } 
} 

Oder könnten Sie Nested Eager Loading

$group = Group::with(['messages.user'])->find($groupID); 
$group->messages[0]->user->firstname 
+0

Ich wusste nichts über die '$ mit'-Eigenschaft. Wo ist das in den Dokumenten? Das sieht ideal aus. – BugHunterUK

+0

Ich kann auch nicht in den Dokumenten finden. Sie finden es in der Model-Klasse. [Siehe diese Zeile] (https://github.com/laravel/framework/blob/3b7181e728d27a641e953ac22e93d91f87e46888/src/Illuminate/Database/Eloquent/Model.php#L182) –

1

Erstellen Sie neue Beziehung in Message Modell:

public function user() 
{ 
    return $this->belongsTo('\App\User'); 
} 

laden die beiden Beziehungen:

$group = Group::with('messages', 'messages.user')->find($groupID); 

foreach ($group->messages as $message) { 
    $message->user->firstname; 
} 

https://laravel.com/docs/5.3/eloquent-relationships#eager-loading

+0

Wenn es eine '' 'with'''-Klausel ist und es eine hasMany-Beziehung zwischen Nachrichten und Gruppe gibt, dann denke ich, dass die zurückgegebene Nachricht eine Sammlung von Benutzern und kein einzelnes Objekt enthalten wird. – Dev

1

Sie haben die Benutzer zugreifen, bevor direkt den Vorname zugreifen.

$group->messages[0]->user->firstname;

Die Art und Weise schrieb man es bedeutet, dass die Nachricht einen Vornamen hat.

Verwandte Themen