4

I've got a function which returns database notifications of a user (the User model is Notifiable):

return $user->notifications()->get();

The result returned is like this:

[
    {
        "id": "5d6548d3-1f9b-4da5-b332-afbf428df775",
        "type": "Meysam\\Notification\\Classes\\CommentCreated",
        "notifiable_id": 1,
        "notifiable_type": "RainLab\\User\\Models\\User",
        "data": {
            "userId": 2,
            "commentId": 18
        },
        "read_at": null,
        "created_at": "2018-03-05 09:58:34",
        "updated_at": "2018-03-05 09:58:34"
    },
    {
        "id": "2e22e24e-a972-4a30-afeb-0049a40966a7",
        "type": "Meysam\\Notification\\Classes\\CommentCreated",
        "notifiable_id": 1,
        "notifiable_type": "RainLab\\User\\Models\\User",
        "data": {
            "userId": 3,
            "commentId": 17
        },
        "read_at": null,
        "created_at": "2018-03-05 09:38:38",
        "updated_at": "2018-03-05 09:38:38"
    }
]

What's the best way to modify this collection before returning it? For example, I want to remove the "id" field from objects, change the value of "type" field to "CommentCreated", and add new fields like "url", "username", "email", etc to each item. Is it a good idea to add hidden, visible and append attributes to DatabaseNotification model class (if so, how)? Are API Resources useful here?

B Faley
  • 17,120
  • 43
  • 133
  • 223
  • 1
    check this : https://laracasts.com/discuss/channels/laravel/how-to-add-a-new-element-to-every-item-of-collection?page=1 – Bugfixer Mar 05 '18 at 07:04
  • 1
    Yes, make use of API Resources or [spatie/laravel-fractal](https://github.com/spatie/laravel-fractal) – linktoahref Mar 05 '18 at 07:25
  • 1
    Use API resources. It's the perfect solution for this, as you should _not_ be modifying the actual notification model class. – Martin Bean Mar 05 '18 at 14:52

3 Answers3

2

If you want to just change the return value of a collection, then this can be done like this way:

$user->notifications()->get()->map(function($item) {
   unset($item['id']); //remove id
   $item['type'] = "CommentCreated"; //change the value of "type" field
   $item['url'] = "url content"; //add new data
   $item['username'] = "username content"; //add new data
   $item['email'] = "email content"; //add new data
   return $item;
});
Alex
  • 2,707
  • 4
  • 29
  • 42
1

For Laravel 5.5+

use API Resources.

For Laravel < 5.5

As suggested by @linktoahref, It is good idea is to use fractals.

By definition, REF: http://fractal.thephpleague.com/

Fractal provides a presentation and transformation layer for complex data output, the like found in RESTful APIs, and works really well with JSON. Think of this as a view layer for your JSON/YAML/etc.

You can use fractals to convert data to appropriate format, when working with laravel it is a good idea to create fractals for each models and use whenever it is required. It can accept a model and perform transformation on each fields and return in proper data format.

spatie/laravel-fractal is a good package to get start with fractals.

Jithin Jose
  • 1,761
  • 2
  • 19
  • 35
0

By default Laravel uses the full class name of the notification as a type, If you want to customise the type of the notification in the database use this method in your Notification class:

/**
 * Get the type of the notification being stored.
 *
 * @return string
 */
public function databaseType()
{
    return 'custom.name';
}
MohKoma
  • 964
  • 9
  • 9