简体   繁体   中英

Laravel eloquent model model attribute casting (Which attribute types should I cast?)

I am not sure I fully understand Laravel Eloquent attribute casting. According to documentation, ( https://laravel.com/docs/8.x/eloquent-mutators#attribute-casting ), these are the supported types:

integer, real, float, double, decimal:, string, boolean, object, array, collection, date, datetime, timestamp, encrypted, encrypted:object, encrypted:array, and encrypted:collection

So far, I've only used date casting on my models (when the fields were stored as timestamps in the db), like this:

protected $dates = [
    'modified_at', 'published_at'
];

I also understand the need for attribute casting to boolean when the values are stored as integers (0 or sth else).

But what about other attribute types (integers, for example), should I always do attribute casting? Or just when the field in the database is of a different type? What are the use cases or what is the best practice with other attributes?

(I can't, for example, imagine creating a string field in migrations, then saving some number inside it as string and then casting it back into an integer on the model?)

By default, attributes will be casted to the type of column defined in the table. So, if your column is an integer, then it will be casted as int .

But, what happens if you want to modify this behavior for specific fields? That's when attribute casting enters the scene.

For example, imagine we have in a table called projects a column named config of type json in which we can store additional configuration elements for each project.

In my case, it'd be useful to be able to handle this data as an array . So, instead of receiving a string or object , we can just deal with a simple array . To do this, we just:

class Project extends Model
{
    // ...

    protected $casts = [
        'config' => 'array',
    ];

    // ...
}

This way, whenever we use Eloquent to fetch projects from the database, each record will have that property as an array . And also, it will be converted back to json when trying to store/update records.

Related to the case you specified (saving element as a string but then retrieve it as an integer ) is totally possible of course. You'll need to set both the accessor and the mutator for that field. For an attribute named number :

/**
 * This will be called when fetching the element.
 */
public function getNumberAttribute($value)
{
    return (int)$value;
}

/**
 * This will be called when storing/updating the element.
 */
public function setFirstNameAttribute($value)
{
    $this->attributes['number'] = (string)$value;
}

Now, a reason to ever need to make this? Well, you could be dealing with a database not properly well designed, or with a production database that is being used by multiple systems and changes in the db are hard to accomplish. In those cases you could make use of this kind of value manipulation to work as you want in your app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM