Home > Net >  How to alter retrieved data dynamically for all models
How to alter retrieved data dynamically for all models

Time:04-12

Every time records are retrieved from the database, I want to intercept the data in the observer so that I can change its value, then return the altered records to the controller.

I currently have a base model where I have set up an observer, so that every time data is retrieved, it triggers the following bit of code :

public function retrieved($data)
{
    $data->field = 'new value';
//return to controller
}

The problem is that the retrieved event happens after the controller receives the data, which means that any alterations made to the model are not available to the controller.

Is there anyway to send this altered data back to the controllers. Am I even going about this the right way ? Is there a better solution for my aims ?

CodePudding user response:

In this case an accessor seem like a good choice since you want to modify the result when you access a property. A mutator is for when you want to modify the value when you update a property value.

To retrieve the original value you can use $someObj->getRawOriginal('property');

Also, you can append custom properties to a model (using class property $appends) with their own accessors if needed.

CodePudding user response:

Maybe you should look at Laravel mutators

Since you are using laravel 8, you should use old school way of defining mutators.

Like this:

class SomeModel {
  ...
    /**
    * Get field attribute
    * Called when controller or view calls `->field` property
    * If you want to make it work on `some_field` then, rename it with `getSomeFieldAttribute`
    */
    public function getFieldAttribute($current_field_value)
    {
      // return whatever you want after calculation
      return 'new value ' . $current_field_value;
    }
  ...
}

With same logic you can use setFieldAttribute funtion as well.

CodePudding user response:

I think what you need is a transformer, that will transform the data that you retrieved from the DB or some source, which can then be used within the same controller or passed on to different functions (controller).

Have a look at Fractal Transformers

SomeModelTransformer.php

<?php

namespace App\Transformers;

use App\Models\SomeModel;
use League\Fractal\TransformerAbstract;

class SomeModelTransformer extends TransformerAbstract
{
    /**
     * A Fractal transformer.
     *
     * @param SomeModel $someModel
     * @return array
     */
    public function transform(SomeModel $someModel): array
    {
        return [
            'name' => $someModel->name . " world",
        ];
    }
}

SomeModel.php

<?php

namespace App\Models;

class SomeModel {
    public $name;

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

}

use App\Models\SomeModel;
use App\Transformers\SomeModelTransformer;

$someModel = new SomeModel('hello');
$transformedData = (new SomeModelTransformer)->transform($someModel);

$transformedData

[
  "name" => "hello world",
]
  • Related