Laravel 5 Eloquent,如何动态设置强制转换属性

时间:2015-08-06 04:47:35

标签: php laravel casting laravel-5 eloquent

在laravel 5.1中有一个名为属性转换的新功能,在此有详细说明: http://laravel.com/docs/5.1/eloquent-mutators#attribute-casting

我的问题是,可以动态地进行属性转换吗?

例如,我有一个包含列的表:

id | name          | value       | type    |
1  | Test_Array    | [somearray] | array   |
2  | Test_Boolean  | someboolean | boolean |

可以设置value属性强制转换,取决于type字段,它在写入(创建/更新)和提取中都有效吗?

2 个答案:

答案 0 :(得分:4)

您需要在模型类中覆盖Eloquent模型的 getCastType()方法:

protected function getCastType($key) {
  if ($key == 'value' && !empty($this->type)) {
    return $this->type;
  } else {
    return parent::getCastType($key);
  }
}

您还需要将添加到 $ this->强制转换,以便Eloquent将该字段识别为强制转换。如果您未设置类型,则可以将默认投射放在那里。

<强>更新

从数据库中读取数据时,上述工作非常有效。撰写数据时,您必须确保在之前设置类型。有两个选项:

  1. 始终传递一个属性数组,其中类型键出现在键之前 - 此时模型的 fill()方法尊重处理数据时键的顺序,但它不是面向未来的。

  2. 在设置其他属性之前,请明确设置类型属性。可以使用以下代码轻松完成:

    $model == (new Model(['type' => $data['type']))->fill($data)->save();
    

答案 1 :(得分:1)

访问字段时使用的$casts属性,而不是从数据库中获取的属性。因此,您可以在填充模型后更新$casts属性,并且只要您访问value字段,它就可以正常工作。您只需要确定在更改$casts字段时如何更新type属性。

一个可能的选择是覆盖fill()方法,以便首先调用父fill()方法,然后使用{{1}中的数据更新$casts属性} field。

另一个可能的选择是滥用mutator功能,并在type字段上创建一个mutator,这样每当它发生变化时,它都会更新type属性。