Hamed Adil
Hamed Adil

Reputation: 483

Access attribute of a 'hasOne' related object

In my User class I have this function:

public function profile() {
    return $this->hasOne('App\Profile');
}

In the controller I used $users = User::all() to get all the users and then pass it to the view using with('users', $users)

In the view where I want to display all of my users profiles I used foreach loop to get to each user data like:

@foreach($users as $user)
<div> {{ $user->profile->some_prfiles_table_column_name }} </div>

But i got an error, So I had to access it using square brackets like this:

{{ $user->profile['some_profiles_table_column_name'] }}

And in another view, where i retrieved only one user by id User::find($id) then i can access the user profile attributes normally as an object NOT array, Like:

{{ $user->profile->some_profiles_table_column_name }} 

What i want to understand is Why i'm getting an array instead of an object? Is there is something wrong or this is normal in laravel?

Thanks in advance

Upvotes: 1

Views: 1119

Answers (1)

patricus
patricus

Reputation: 62278

You're not getting an array. Eloquent Models implement PHP's ArrayAccess interface, which allows you to access the data as if it were an array.

The problem you're having is that one of your users does not have an associated profile. When that happens, $user->profile will be null. If you attempt to access an object property on null, you'll get a "Trying to get property of non-object" error. However, if you attempt to access an array property of null, it'll just return null without throwing an error, which is why your loop appears to work as an array.

Illustrated with code:

foreach ($users as $user) {
    // This will throw an error when a user does not have a profile.
    var_export($user->profile->some_profiles_table_column_name);

    // This will just output NULL when a user does not have a profile.
    var_export($user->profile['some_profiles_table_column_name'];
}

So, presumably, you'll want to handle the situation in your code when the user does not have a profile:

@foreach($users as $user)
<div> {{ $user->profile ? $user->profile->some_profiles_table_column_name : 'No Profile' }} </div>
@endforeach

Upvotes: 1

Related Questions