1
votes

I am using Laravel Eloquent models to model these tables:

users: id firstName lastName password email

posts: id user_id title content

with Post model having a relation of hasOne ('User') and User model having a calculated attribute:

protected $appends = ['name'];

public function getNameAttribute(){
    return $this->attributes['name'] = $this->firstName.' '. $this->lastName;
}

I need to use eager loading to get only the name of the author of the post, and not all the columns in the users table.

I tried:

$result = Post::with(
    [
        'user' => function( $query ){
            $query->select('name');
        }
    ]
)->get();

but apparently name is not a column in the table but only a calculated attribute. so how can I get this done?

1

1 Answers

1
votes

You're not going to be able to use your accessor inside a query. You've got two options:

Option one: duplicate your accessor logic inside your query:

$result = Post::with(
    [
        'user' => function( $query ){
            $query->selectRaw("id, CONCAT_WS(' ', firstName, lastName) as name");
        }
    ]
)->get();

print_r($result->first()->user->name);

Since your name attribute is now coming from the query, this would require that you also modify your accessor to use the existing value if it already exists:

public function getNameAttribute($value = null) {
    $name = $value ?: $this->firstName.' '.$this->lastName;
    return $this->attributes['name'] = $name;
}

Option two: just make sure to select all the fields needed by your accessor:

$result = Post::with(
    [
        'user' => function( $query ){
            $query->select('id, firstName, lastName');
        }
    ]
)->get();

print_r($result->first()->user->name);