Reputation: 8968
I'm trying to figure out how to eager load data from a related table. I have 2 models Group
and GroupTextPost
.
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');
}
}
What I'm trying to do is eager load the user
when fetching group text posts so that when I pull the messages the user's name is included.
I've tried doing it like so:
public function messages()
{
return $this->hasMany('\App\Models\GroupTextPost')->with('user');
}
... and calling like so:
$group = Group::find($groupID);
$group->messages[0]->firstname
But I get an error:
Unhandled Exception: Call to undefined method Illuminate\Database\Query\Builder::firstname()
Is this possible to do with Eloquent?
Upvotes: 8
Views: 14945
Reputation: 171
You should not eager load directly on the relationship. You could eager load the user always on the GroupTextPost model.
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');
}
}
Or you could use Nested Eager Loading
$group = Group::with(['messages.user'])->find($groupID);
$group->messages[0]->user->firstname
Upvotes: 12
Reputation: 163968
Create new relationship in Message
model:
public function user()
{
return $this->belongsTo('\App\User');
}
Load both relations:
$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
Upvotes: 1
Reputation: 11
You have to access the user before accessing directly the firstname.
$group->messages[0]->user->firstname;
The way you wrote it means the message has a firstname.
Upvotes: 1