Framework: Get relationship from notification by ID

Created on 4 Oct 2016  路  2Comments  路  Source: laravel/framework

Is it possible to retrieve relationships given a notification id?

For example, using this snippet from the Laravel docs:

/**
 * Get the array representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toArray($notifiable)
{
    return [
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ];
}

Assuming there exists an Invoice model and table, how can I retrieve the Invoice record by using the invoice_id value in the notification data when getting user notifications:

$user = App\User::find(1);

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

Here's another example to clarify what I need.

Let's say I want to notify a user about a new post that I've made.

I don't want to store the entire Post record in the notification, because the post contents can be edited (meaning that if I edited the post, the user should be able to see those edits in the notification). So instead, I just want to store the id of the Post so that I can later use that to retrieve the Post record from the posts table.

All 2 comments

Invoice::find($notification->invoiceId)

Hello,
A little tricky but it works, even tho i'll wait for an official trick.

For API

{
    "post_id": 10
}

If you want to get the post model in the response:

  1. Create a Resource Collection
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class Notification extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection->map(function ($notification) {
                $notification = $notification->toArray();

                // Add post
                $notification = $this->getModel(
                    'post', // post_id
                    $notification, // the array
                    \App\Post::class, // The post model
                    \App\Http\Resources\NotificationPost::class // You can also avoid this
                );

                return $notification;
            })
        ];
    }

    /**
     * Get the model by id.
     * 
     * @param  string  $type
     * @param  array  $data
     * @param  string  $model
     * @param  string|null  $resource
     * @return array
     */
    protected function getModel(string $type, array $data, string $model, string $resource = null)
    {
        if (isset($data['data']["{$type}_id"])) {
            $model = new $model();

            $model = $model->findOrFail(
                $data['data']["{$type}_id"]
            );

            $data['data'][$type] = $resource ? new $resource(
                $model
            ) : $model;

            // Get rid of the {$type}_id
            unset($data['data']["{$type}_id"]);
        }

        return $data;
    }
}
  1. Create a Resource and name it NotificationPost
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class NotificationPost extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'body' => $this->body,
            'created_at' => $this->created_at
        ];
    }
}

Usage:

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Resources\Notification as NotificationCollection;

class Notifications extends Controller
{
    /**
     * Get notifications.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function get(Request $request)
    {
        return new NotificationCollection(
            $request->user()->notifications()->paginate(
                20
            )
        );
    }
}

You can change the code and make it compatible for web.
Good luck!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

digirew picture digirew  路  3Comments

JamborJan picture JamborJan  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments

PhiloNL picture PhiloNL  路  3Comments

gabriellimo picture gabriellimo  路  3Comments