当响应为JSON并且字段包含数字时,模型访问器不起作用

时间:2018-11-23 10:31:31

标签: php laravel laravel-5

我有许多“获取”变种器,它们对数据进行解密,以便在视图中可读。这些变量是数据库中字段的名称。除2之外,这些功能大多数都能工作。这2个mutator的唯一区别是mutator函数名称包含数字。

有效的增幅器示例:

public function getDateOfBirthAttribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

不起作用的增幅器示例:

public function getAddressLine1Attribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

public function getAddressLine2Attribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

表中的字段名称:

  • address_line_1
  • address_line_2

关于这一切的非常奇怪的事情是,当响应不是json时,增变器将按预期工作并解密该字段。 (例如,使用return view('view.name', compact($user))),但是当我将这些数据放入JSON响应中(例如return response()->json([$user]);时,这2个地址行修改器将不起作用,并返回未修改的字段。

我尝试将return "test"添加到这两个mutator中,以查看它是否甚至击中了函数,但事实并非如此。

为什么在这种情况下JSON会阻止增变器工作?函数名称中的数字可能有问题吗?我可以重命名数据库中的字段吗?

1 个答案:

答案 0 :(得分:2)

我现在无法验证这一点,但我认为它可能与laravel计算snake_casecamel_case的方式有关。

基本上,当您请求$user->address_line_1之类的字段时,laravel会转换驼峰(AddressLine1)中的字段并检查自定义访问器,然后找到它并返回正确的修改值。

但是,当模型被序列化为Json时,它将执行相反的操作:它试图通过查看访问器来检测需要修改哪个字段。因此,它找到了getAddressLine1Attribute并将其转换为snake_case ..并产生了address_line1,一个错误的字段。

这里的基本问题是address_line_1address_line1都具有相同的camelCase表示形式,因此不可能可靠地将转换反向转换为camelCase。

您可以尝试的一种方法是将访问器定义为getAddressLine_1Attribute,但是在直接访问字段($user->address_line_1)时将无法使用

您可以定义它以使用先前定义的访问器,因此您无需重复代码:

public function getAddressLine_1Attribute($value)
{
    return $this->getAddressLine1Attribute($value);
}

public function getAddressLine1Attribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

编辑:我的理论已经通过对camel_case()和snake_case()辅助函数的一些测试得到了证实

相关问题