Is there a way to access relationship attributes as own in laravel model?

Viewed 4938

I have 2 tables: users and users_details

-- users has 3 columns [id,username,password]

-- users_details has [id,user_id,name,address]

I have models for each of them with a relation from users to users_details.

    public function details()
    {
        return $this->hasOne(UserDetails::class, 'user_id', 'id');
    }

my question comes here: Is there a way to access UsersDetails attributes as User only.

e.g: {{ $user->name }} : {{ $user->address }} instead of {{ $user->details->name }} : {{ $user->details->address }}

Keep in mind that these tables are only examples and don't have their real range of columns. I need this to implement Laravel/Cashier but this plugin needs 4 new columns in [users] table and I want to put them in [users_details] table.

I haven't tried anything because I don't really know if it is possible. Except for the moment the only workaround that I know of is to make getNameAttribute method in User:

    public function getNameAttribute()
    {
        return $this->details->name;
    }
3 Answers

I'm not sure I would recommend it as it will just add magic to how things work and might be hard to understand 6 months from now.

But you could do something like that in your User model.

Edited

public function getAttribute($key)
{
    // If attribute exists on the user, return that
    return parent::getAttribute($key)
        // otherwise fallback to details attribute
        ?? optional($this->details)->getAttribute($key);
}

yes. you can do it in controller before pass $user to your view. like this.

$user->load('details');

then you pass the $user to your view like this:

return view('your_view' , compact('user'));

then in your view use the following code:

{{ $user->details_table_field }}

you can search about eager loading : https://laravel.com/docs/5.7/eloquent-relationships#eager-loading

I think using Laravel Query Builder and Laravel Scope is also another option in this problem.

To do that you need to add the following line of codes.

In your User Model:

public function scopeUserDetails($query){
    return $query->join('users_details', 'users.id', '=', 'users_details.user_id');
}

In your Controller:

$users = User::userDetails()->all(); #get all users
//dd($users); #dumping results
return view("view_file", compact('users')); #passing data to view

In your Blade View File:

 @foreach ($users as $user)
      {{ $user->name }} : {{ $user->address }}
 @endforeach
Related