2016-12-15 4 views
2

Я пытаюсь выяснить, как загружать данные из связанной таблицы. У меня есть 2 модели Group и GroupTextPost.Eloquent - Eager Загрузка отношений

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

То, что я пытаюсь сделать, это стремится нагружают user при извлечении группы текстовых сообщений, так что, когда я тяну сообщения, в которые включено имя пользователя.

Я пытался делать это так:

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

... и называя так:

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

Но я получаю сообщение об ошибке:

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

Является ли это можно сделать с Eloquent?

+1

Try '' '$ т = $ группы-> сообщения() -> получить()' '', а затем '' '$ m [0] -> user [0] -> first_name;' '' – Dev

+0

Сообщения будут иметь имя или имя пользователя? – Dev

+0

Пользователь @Dev имеет первое имя. – BugHunterUK

ответ

3

Вы не должны стремиться к загрузке непосредственно по отношению. Вы всегда можете загружать пользователя всегда в модели GroupTextPost.

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

Или вы могли бы использовать Nested Eager Loading

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

Я не знал о свойстве '$ with'. Где это в документах? Это выглядит идеально. – BugHunterUK

+0

Я также не могу найти в документах. Вы можете найти его в классе модели. [См. Эту строку] (https://github.com/laravel/framework/blob/3b7181e728d27a641e953ac22e93d91f87e46888/src/Illuminate/Database/Eloquent/Model.php#L182) –

1

Создание новых отношений в Message модели:

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

Загрузить оба соотношения:

$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

Если это '' 'with''' и есть отношение hasMany между сообщениями и группой, я думаю, что возвращенное сообщение будет иметь коллекцию пользователя, а не отдельный объект. – Dev

1

Вы должны получить доступ к пользователю перед обращением непосредственно ПгвЬЫата.

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

как вы написали это означает, что сообщение имеет ПгвЬЫат.

Смежные вопросы