rap-2-h
rap-2-h

Reputation: 31998

Retrieve model from notification

With Laravel, I can create database notifications.

Assuming, my notifications are about Resources (a model named Resource), I can give a resource instance to the notification constructor:

public function __construct(Resource $resource)
{
    $this->resource = $resource;
}

// ... 

public function toArray($notifiable)
{
    return [
        'resource_id' => $this->resource->id
    ];
}

I would like to load notifications for a user and display some resources information. I can get all notifications and do something like this:

foreach ($user->notifications as $notification) {

    $resource_id = $notification->resource_id;
    $resource = Resource::find($resource_id);

    // Do something with resource information...
    echo $resource->name;

}

But it's slow (one query for each notification) and not à la Laravel. I would prefer something like:

foreach ($user->notifications as $notification) {

    // Do something with resource information...
    echo $notification->resource->name;

}

Ideally, it would like to have some kind of eager loading. Is there an elegant (or at least working) way to do this?

Upvotes: 3

Views: 884

Answers (1)

apokryfos
apokryfos

Reputation: 40683

You can reduce your queries down to one by doing:

Resource::whereIn('id', collect($user->notifications)->pluck('resource_id'))

This will only perform a single SQL query.

Digging deeper into the Laravel database notifications. The Laravel boilerplate notification may be able to work with:

class User extends Model {
   // ...
   public function resourceNotifications() {
       $this->morphToMany(Resource::class, 'notifiable', 'notifications');
   }
}

Then retrieving all the corresponding notifications is as simple as:

$notifications = $user->resourceNotifications()->get();

Have not tested that part though.

Upvotes: 2

Related Questions