我有一节课:
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);
});
}
}
industries
是数据库中的json字段。
上面的代码实现了我的目标--如果访问给定字段,则来自给定字段的值将为json_decoded,然后转换为Industry
数组。当保存此模型时,行业将保存为每个$casts
的json。
我想要做的是摆脱getIndustriesAttribute
,让Laravel将我的json转换为对象的数组--理想情况下,我的代码如下所示:
class Account extends Model
{
protected $casts = [
'industries' => Industry::class.'[]',
];
}
当然,这不起作用,但它给出了我想要发生的事情--一个对象数组应该是json_encode / json_decoded (Industry是一个普通的对象,所以它不需要序列化)。
作为一种解决办法,我写了这篇文章:
<?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());
}
};
}
}
可以用的
protected $casts = [
'industries' => Industry::class.':[]',
];
但是如果有一个本地的Laravel来处理这种情况,我会很感激的。
发布于 2021-04-11 01:51:22
您可以使用我的库,它有一个如何使用Laravel自定义强制转换- https://github.com/morrislaptop/laravel-popo-caster#2-configure-your-eloquent-attribute-to-cast-to-it的数组转换的示例。
发布于 2021-04-08 11:00:07
如果您坚持以这种方式转换属性,那么您应该查看自定义铸型。
否则,我建议您查看@Bodhi关于使用一对多关系的评论。
以下是对您来说自定义强制转换的样子:
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,
];
}
https://stackoverflow.com/questions/67009253
复制相似问题