Средства доступа к модели не работают, если ответом является JSON, а поле содержит число - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть много мутаторов get, которые расшифровывают данные, чтобы их можно было прочитать в представлении.Эти мутаторы являются именами полей в БД.Большинство из них работают за исключением 2. Единственное различие с этими двумя мутаторами состоит в том, что имена функций мутатора содержат числа.

Пример мутатора, который работает:

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" этим двум мутаторам, чтобы увидеть, поражает ли она функцию, но это не так.

Почему в этом случае JSON останавливает работу мутатора? Может ли быть проблема с числами в имени функции?Могу ли я переименовать мои поля в БД?

1 Ответ

0 голосов
/ 23 ноября 2018

Я не могу проверить это сейчас, но я думаю, что это может быть связано с тем, как laravel вычисляет snake_case и camel_case.

В основном, когда вы запрашиваете поле типа $user->address_line_1, laravelпреобразует поле в camelCase (AddressLine1) и проверяет наличие пользовательских средств доступа, находит его и возвращает правильное измененное значение.

Однако, когда модель сериализуется в Json, она выполняет противоположную операцию: онапытается определить, какое поле необходимо изменить, глядя на методы доступа.Таким образом, он находит getAddressLine1Attribute и преобразует его в snake_case .., получая address_line1, неправильное поле.

Основная проблема здесь в том, что и address_line_1, и address_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() вспомогательные функции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...