phpjsonlaraveleloquentrelationships

Laravel Eloquent relationship not an object when doing anything but dd()


I have a seemingly stupid and crazy situation. I have activity logs for users, my user model has this relationship in it:

public function activityLogs()
{
    return $this->hasMany(Log::class);
}

Pretty straight forward and when I check a single user object for all logs it works fine. So on one page I only want the last log recorded, I need the created_at date from it. When loading the users I run

$users = User::with(
    [
        'activityLogs' => function ($query) {
            $query->orderBy('created_at', 'desc')
                  ->limit(1);
        }
    ]
)

and this returns the last log as expected. When I want to get the date if I run

dd($users->first()->activityLogs()->first()->created_at->format("d/m/Y"));

I get a string output with the date as expected. However, when I try to do anything else with it, such as putting it into a variable or echoing it out I just get an error that activityLogs()->first() is not an object. The code in my view (inside a foreach ($users as $user) loop) is

{{ $user->activityLogs()->first()->created_at }}

and it just gives me the error

ErrorException (E_ERROR) Trying to get property of non-object (View: ROOT_PATH/resources/views/acp/partials/profiles.blade.php) (View: ROOT_PATH/resources/views/acp/partials/profiles.blade.php)

I've tried accessing activityLogs as both a collection and hasMany object. I've also tried converting the resultant JSON string back with json_decode but it still complains about not being an object.

Why? Why can I get the value perfectly fine when using dd but when I try anything else it's suddenly a JSON string? I've tried googling this but no matter what combination of words I try it just comes up with questions and guides on how to convert an Eloquent object into JSON, the opposite of what I want.


Solution

  • You need to check to make sure the user has a last activity. first() will return null if there aren't any logs. You should check for existence in your loop.

    @foreach($user as $user)
        {{$user->activityLogs->count() > 0 ? $user->activityLogs->first()->created_at : 'User Has No Activity!'}}
    @endforeach
    

    Or use blade's @if/@else

    @foreach($user as $user)
        @if($user->activityLogs->count() > 0)
            {{$user->activityLogs->first()->created_at}}
        @else 
            'User Has No Activity!'
        @endif  
    @endforeach