Laravel 5 Eloquent,如何动态设置强制转换属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31847050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel 5 Eloquent, How to set cast attribute dynamically
提问by antoniputra
In laravel 5.1 there is new feature called Attribute Casting, well documented at here : http://laravel.com/docs/5.1/eloquent-mutators#attribute-casting
在 laravel 5.1 中有一个名为 Attribute Casting 的新功能,这里有详细记录:http: //laravel.com/docs/5.1/eloquent-mutators#attribute-casting
My question is, it is possible to make attribute casting dynamically ?
我的问题是,可以动态进行属性转换吗?
for example, I have a table with columns :
例如,我有一个带有列的表:
id | name | value | type |
1 | Test_Array | [somearray] | array |
2 | Test_Boolean | someboolean | boolean |
it is possible to set value
attribute cast, depends on type
field, that work both in write(create/update) and fetch ?
可以设置value
属性转换,取决于type
字段,在 write(create/update) 和 fetch 中都有效?
回答by jedrzej.kurylo
You'll need to overwrite Eloquent model's getCastType()method in your model class:
您需要在模型类中覆盖Eloquent模型的getCastType()方法:
protected function getCastType($key) {
if ($key == 'value' && !empty($this->type)) {
return $this->type;
} else {
return parent::getCastType($key);
}
}
You'll also need to add valueto $this->castsso that Eloquent recognizes that field as castable. You can put the default cast there that will be used if you didn't set type.
您还需要为$this->casts添加值,以便 Eloquent 将该字段识别为castable。如果您没有设置type,您可以将默认演员表放在那里。
Update:
更新:
The above works perfectly when reading data from the database. When writing data, you have to make sure that typeis set before value. There are 2 options:
从数据库读取数据时,上述方法完美无缺。写入数据时,您必须确保在value之前设置type。有2个选项:
Always pass an array of attributes where typekey comes before valuekey - at the moment model's fill()method respects the order of keys when processing data, but it's not future-proof.
Explicitely set typeattribute before setting other attributes. It can be easily done with the following code:
$model == (new Model(['type' => $data['type']))->fill($data)->save();
始终传递类型键在值键之前的属性数组- 目前模型的fill()方法在处理数据时尊重键的顺序,但它不是面向未来的。
在设置其他属性之前显式设置类型属性。可以使用以下代码轻松完成:
$model == (new Model(['type' => $data['type']))->fill($data)->save();
回答by patricus
The $casts
attribute it used whenever you access a field, not when it is fetched from the database. Therefore, you can update the $casts
attribute after the model has been populated, and it should work fine whenever you access the value
field. You just need to figure out how to update the $casts
attribute when the type
field is changed.
$casts
每次访问字段时使用的属性,而不是从数据库中获取时使用的属性。因此,您可以$casts
在填充模型后更新属性,并且无论何时访问该value
字段它都应该可以正常工作。您只需要弄清楚如何$casts
在type
字段更改时更新属性。
One potential option would be to override the fill()
method so that it calls the parent fill()
method first, and then updates the $casts
attribute with the data in the type
field.
一种可能的选择是覆盖该fill()
方法,以便它首先调用父fill()
方法,然后$casts
使用type
字段中的数据更新属性。
Another potential option would be to abuse the mutator functionality, and create a mutator on the type
field, so that whenever it changes, it would update the $casts
attribute.
另一个可能的选择是滥用 mutator 功能,并在type
字段上创建一个 mutator ,以便每当它发生变化时,它都会更新$casts
属性。