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);
});
}
}
withindustries
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 ofIndustry
. When this model is saved, industries will be saved as json per$casts
.
What I'd like to do is get rid ofgetIndustriesAttribute
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.
You could use my library, it has an example of how to cast to/from arrays with Laravel custom casts - https://github.com/morrislaptop/laravel-popo-caster#2-configure-your-eloquent-attribute-to-cast-to-it
If you're adamant about casting your attribute this way, then you should check out Custom Casts.
Otherwise I would recommend that you check out the comment by @Bodhi regarding using a one-to-many relation.
Here is what Custom Casts might look like for you:
app/Casts/Industries.php
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class Industries implements CastsAttributes
{
/**
* Cast the given value.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return array
*/
public function get($model, $key, $value, $attributes)
{
return collect(json_decode($value, true))->map(function ($industry) {
return new Industry($industry);
});
}
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param array $value
* @param array $attributes
* @return string
*/
public function set($model, $key, $value, $attributes)
{
return json_encode($value);
}
}
app/Models/Account.php
<?php
use App\Casts\Industries;
class Account extends Model
{
protected $casts = [
'industries' => Industries::class,
];
}
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Find the answer in similar questions on our website.
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.
PHP (from the English Hypertext Preprocessor - hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/
Laravel is a free open source PHP framework that came out in 2011. Since then, it has been able to become the framework of choice for web developers. One of the main reasons for this is that Laravel makes it easier, faster, and safer to develop complex web applications than any other framework.
https://laravel.com/
Welcome to the Q&A site for web developers. Here you can ask a question about the problem you are facing and get answers from other experts. We have created a user-friendly interface so that you can quickly and free of charge ask a question about a web programming problem. We also invite other experts to join our community and help other members who ask questions. In addition, you can use our search for questions with a solution.
Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.
Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.