OrbitalNiner's avatar

Get causer data within foreach using "Spatie Activity Log"

I have installed the Spatie Activity Logger and all is working as it should. I have a page for showing the systems activity log and also this is working as it should, except...

I need to display data on who caused the log, and somehow I am unable to get this to work. I could load it inside the blade for each but this does not seem to be the correct way.

My code for loading the logs in a livewire component;

 public function render(): \Illuminate\Contracts\View\View|\Illuminate\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View|\Illuminate\Contracts\Foundation\Application
    {
        /** Admin only, returns no access if no admin */
        auth()->user()?->can('admin');

        $logs = Activity::where(function ($query) {
            $query->where('properties', 'like', '%'.$this->search.'%')->orWhere('event', 'like', '%'.$this->search.'%')->orWhere('description', 'like', '%'.$this->search.'%');
        })->when($this->sortField, function ($query) {
            $query->orderBy($this->sortField, $this->sortAsc ? 'asc' : 'desc');
        })->when($this->showTrashed, function ($query) {
            $query->onlyTrashed();
        })->when($this->event, function ($query) {
            if ($this->event != 'all') {
                $query->where('event', $this->event);
            }
        })->when($this->request_ip, function ($query) {
            $query->whereJsonContains('properties', ['request_ip' => $this->request_ip]);
        })->where('log_name', 'mynth_core')->paginate($this->limit);

        return view('livewire.admin.admin-activity-log', [
            'logs' => $logs,
            'events' => Activity::pluck('event')->where('log_name', 'mynth_core')->unique(),
        ]);
    }

I am new to Laravel and would appreciate a little help on this one!

Thanks in advance for any help provided.

0 likes
2 replies
LaryAI's avatar
Level 58

To display the causer data for each activity log, you can use the causer relationship that is provided by the Spatie Laravel Activitylog package. This relationship allows you to access the model that caused the activity. You can eager load the causer relationship when you are querying your logs to avoid the N+1 query problem.

Here's how you can modify your code to include the causer data:

public function render(): \Illuminate\Contracts\View\View|\Illuminate\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View|\Illuminate\Contracts\Foundation\Application
{
    /** Admin only, returns no access if no admin */
    auth()->user()?->can('admin');

    $logs = Activity::with('causer') // Eager load the causer relationship
        ->where(function ($query) {
            $query->where('properties', 'like', '%'.$this->search.'%')
                  ->orWhere('event', 'like', '%'.$this->search.'%')
                  ->orWhere('description', 'like', '%'.$this->search.'%');
        })
        ->when($this->sortField, function ($query) {
            $query->orderBy($this->sortField, $this->sortAsc ? 'asc' : 'desc');
        })
        ->when($this->showTrashed, function ($query) {
            $query->onlyTrashed();
        })
        ->when($this->event, function ($query) {
            if ($this->event != 'all') {
                $query->where('event', $this->event);
            }
        })
        ->when($this->request_ip, function ($query) {
            $query->whereJsonContains('properties', ['request_ip' => $this->request_ip]);
        })
        ->where('log_name', 'mynth_core')
        ->paginate($this->limit);

    return view('livewire.admin.admin-activity-log', [
        'logs' => $logs,
        'events' => Activity::pluck('event')->where('log_name', 'mynth_core')->unique(),
    ]);
}

Now, in your Blade view (livewire.admin.admin-activity-log), you can display the causer data by accessing the causer property on each log entry. Here's an example of how you might do that:

@foreach($logs as $log)
    <tr>
        <td>{{ $log->description }}</td>
        <td>{{ $log->causer->name ?? 'System' }}</td> <!-- Display the causer's name -->
        <!-- ... other columns ... -->
    </tr>
@endforeach

In this example, $log->causer->name is used to display the name of the causer. If the causer is null (which can happen if the causer has been deleted or if the activity was caused by the system), it will display 'System' as a fallback.

Remember to replace name with the actual attribute of your causer model that you want to display (e.g., email, username, etc.).

1 like
OrbitalNiner's avatar

This solved it for me, I could not find this in the documentation or I completely overlooked it.

Please or to participate in this conversation.