7

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?)

1

1 Answer 1

21

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.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, Kenny, that clears it up...cast when need/want to, but not all the time
Clear and very knowledgeable answer. Thank you Kenny!
it was very helpful thank you for taking from your time to explore this i understanded it well from you

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.