John Davidson

php - Using $casts for array of objects

0 comments
Message:


I've got a following class:


class Account extends Model
{
protected $casts = [
'industries' => 'json',
];

public function getIndustriesAttribute($value = null)
{
return collect(json_decode($value, true))->map(function ($industry) {
return new Industry($industry);
});
}
}

with industries being a json field in the database.


The above code does what I'm aiming to do - if given field is accessed, the value from given field will be json_decoded and then transformed into array of Industry. When this model is saved, industries will be saved as json per $casts.


What I'd like to do is get rid of getIndustriesAttribute and make Laravel do a cast of my json to array of objects - ideally my code would look like this:


class Account extends Model
{
protected $casts = [
'industries' => Industry::class.'[]',
];
}

Of course this doesn't work, but it gives an idea what I'd like to happen - an array of objects should be json_encode / json_decoded (Industry is a plain object so it doesn't need to be an serialized).


As a workaround I've written this castable:


<?php

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

trait ArrayableCast
{
public static function castUsing(array $arguments)
{
if (in_array('[]', $arguments)) {
return new class implements CastsAttributes {
public function get($model, $key, $value, $attributes)
{
return collect(json_decode($value, true))->map(function ($item) {
return new (static::class)($item);
})->all();
}

public function set($model, $key, $value, $attributes)
{
return json_encode(collect($value)->map(function ($item) {
return $item->toArray();
})->all());
}
};
}

return new class implements CastsAttributes {
public function get($model, $key, $value, $attributes)
{
return new (static::class)(json_decode($value, true));
}

public function set($model, $key, $value, $attributes)
{
return json_encode($value->toArray());
}
};
}
}

which can be used per


protected $casts = [
'industries' => Industry::class.':[]',
];

but I'd appreciate if there was a native Laravel of handling this scenario.



My Answer:
> 'array'
> 'contacts' => 'array'
> 'address' => 'object'
> ];_}_I want to cast the 'address' attribute as an object. How can I achieve this?

Rate this post

5 of 5 based on 7607 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us