Reputation: 181
So I currently have 3 models Specie
Type
User
. I want to be able to get the name of the last modified user in relation to the Specie
model
The relationships are as follows
Class Specie extends Model {
public function type()
{
return $this->belongsTo('App\Type', 'type_id');
}
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
}
Class Type extends Model {
public function specie()
{
return $this->hasMany('App\Specie', 'type_id');
}
}
Class User extends Model {
public function specie()
{
return $this->hasMany('App\Specie', 'user_id');
}
}
I have tried this
Class Specie extends Model {
public function lastModified()
{
return $this->belongsTo('App\User', 'last_modified_by');
}
}
And then used the below code
$this->type->with(['specie.lastModified' => function ($query) use
($userId) {
$query->where('user_id', $userId);
}])->get();
Unfortunately this does not seem to work
However, by using this code
$this->type->with(['specie' => function ($query) use ($userId) {
$query->where('user_id', $userId);
}])->get();
I am able to get this:
"id": 1,
"type": "Halo",
"created_at": "2019-07-20 13:02:53",
"updated_at": "2019-07-20 13:02:53",
"specie": [
{
"id": 5,
"user_id": 1,
"type_id": 1,
"note": "et",
"created_by": 1,
"last_modified_by": 1,
}
]
However, what I want to get is the name of the last modified person name which is the primary key in the User
model and the foreign key in the Specie
model
This is what I expect to get:
"id": 1,
"type": "Halo",
"created_at": "2019-07-20 13:02:53",
"updated_at": "2019-07-20 13:02:53",
"specie": [
{
"id": 5,
"user_id": 1,
"type_id": 1,
"note": "et",
"created_by": 1,
"last_modified_by": 1,
"last_modified_name": 'gerrard'
}
]
Upvotes: 0
Views: 4369
Reputation: 1150
I used the getKeyName()
method on the related model.
My relationship was a one to many so returned as a Collection
.
Accessing the returned collections first item in collection [0] and then running the getKeyName()
worked.
Below my code first checks if the relation data is filled and that its returned as a Collection (multiple) and that there is atleast 1 item.
if(
$item->relatives
&& $item->relatives instanceof \Illuminate\Database\Eloquent\Collection
&& count($item->relatives)
) {
$relation_key = $item->relatives[0]->getKeyName();
}
I presume you could test if relation is return as a Collection of Models or a single Model is returned.
If a single model is returned you can just:
$item->relative->getKeyName();
Upvotes: 0
Reputation: 2823
From your Eloquent entity relationships:
Specie
and Type(type)
are related (one-to-many)
Specie
and User(user)
are related (one-to-many)
Specie
and User(lastModified)
are related (one-to-many)
User
and Type
are not related
So, for you to include the user name you have to query the Specie
model through the lastModified()
method.
$this->lastModified()->with(['specie' => function ($query) use ($userId) {
$query->where('user_id', $userId);
}])->get();
You should expect a result like this
"id": 1,
"name": "the_user_name"
// any other user data
"created_at": "2019-07-20 13:02:53",
"updated_at": "2019-07-20 13:02:53",
"specie": [
{
"id": 5,
"user_id": 1,
"type_id": 1,
"note": "et",
"created_by": 1,
"last_modified_by": 1,
}
]
From the result, the field(foreign key) last_modified_by
in specie
with value 1
should match the field id
in user
.
Also, I'm assuming the field for your user name is name
. It would be included with the returned user data.
UPDATE
You can not get any user data from the User
table through the Type
table using eager loading except they are related. Ergo, models must be related (i.e. constrained by each other) before they can be nested, for instance using eager loading. See this medium article to better understand this.
Upvotes: 1