0

I am trying to define a model mutator

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Custom_fields extends Model
{
    protected $table = 'custom_fields';

    public function setContentAttribute($value){
        return unserialize($value);
    }
}

and on test controller, tried

Custom_fields::all()[0]->content;

Unfortunately, it is not working; the value is still not an array (serialize)

I want to access the field content and unserialize the value of the field so I can get an array automatically on retrieve, but it's not working.

miken32
  • 42,008
  • 16
  • 111
  • 154
Juliver Galleto
  • 8,831
  • 27
  • 86
  • 164
  • may be it would be `setContentAttribute($value)` – STA Nov 23 '20 at 04:17
  • @sta the field name is '_content' did tried, unfortunately same results – Juliver Galleto Nov 23 '20 at 04:18
  • If Eloquent allows defining `content` and a `_content`, both will have the same mutators functions `setContent` https://github.com/illuminate/database/blob/master/Eloquent/Concerns/HasAttributes.php#L432 – STA Nov 23 '20 at 04:22
  • @sta tried to change _content to content and tried setContentAttribute($value) but unfortunately same, results if I do Custom_fields::all()[0]->content – Juliver Galleto Nov 23 '20 at 04:25
  • 1
    If content is a field which needs to store serialized array data which when retrieved should again be automatically unserialized to array - maybe attribute casting is what you need. protected `$casts = ['_content' => 'array'];` on `Custom_fields` model class. https://laravel.com/docs/8.x/validation#custom-validation-rules – Donkarnash Nov 23 '20 at 05:13

1 Answers1

4

You're trying to "get an array automatically on retrieve" with a method called setContentAttribute. You are confusing accessors and mutators. As the method name implies, the mutator is called when you set the content attribute.

To create an accessor that is called when you get the content attribute:

public function getContentAttribute($value)
{
    return unserialize($value);
}

Likely if this data is to be stored in a serialized form you want your mutator to look like this:

public function setContentAttribute($value)
{
    $this->attributes["content"] = serialize($value);
}

But really, you should not be using these serialization functions at all. Laravel can natively convert objects to JSON for storage in a database. Simply define the property in your model's $casts property and data will be converted automatically when getting or setting the property.

protected $casts = [
    "content" => "array",
];
miken32
  • 42,008
  • 16
  • 111
  • 154