ActiveModel :: Грязные и JSON поля - PullRequest
0 голосов
/ 27 ноября 2018

Я использую ActiveModel :: Dirty для отслеживания изменений, внесенных в форму.Теперь все работает, как я ожидаю.С такими вещами, как телефонные номера, в которых есть тире, когда в форме я просто форматирую их, и тогда телефонный номер не появится в списке .changed, что является ожидаемым поведением.

Однако я столкнулся с проблемой, когда я использую поле jsonb в моей модели профиля.Таким образом, проблема заключается в том, что ActiveModel перечислит поле JSONB как измененное, даже если я отформатирую его специально, чтобы оно выглядело как раньше.Это не ожидаемое поведение.Что еще более странно, так это то, что другая колонка JSONB, которую я имею, не испытывает этого безумия.

Поле JSONB, с которым у меня возникли проблемы, выглядит следующим образом store_accessor :user_details, :names, :other_field store_accessor :bank_details, :bank_city, :bank_name user_details и bank_details - это столбцы jsonb.Некоторые вещи, на которые следует обратить внимание: names - это массив, other_field - строка.bank_city и bank_name - это строки.

Кто-нибудь может пролить свет на то, почему именно user_details борется с этой проблемой, а не с JSON-столбцом: bank_details?

Я подозреваю, что это может быть связано со мной.используя массив внутри: user_details, и я подозреваю, что сравнение отбрасывается где-то в исходном коде ActiveModel, но, возможно, я ошибаюсь?

Редактировать: я обнаружил, что это определенно потому, что я используюмассив для: имен.Я изменил его на строку, и он перестал думать, что столбец JSON был изменен.Собираюсь покопаться в исходном коде ActiveModel, чтобы посмотреть, смогу ли я найти причину.

Редактировать # 2: Почему-то я думал, что решил проблему, ничего не делая, но я дурак и понял, что яудалил что-то в форме.Так что этот вопрос до сих пор не решен для меня.Любое понимание было бы удивительным.Я не могу понять, глядя на исходный код ActiveModel :: Dirty, почему это происходит.Я не совсем уверен, где искать.Пойдем пощечину в byebugs, чтобы посмотреть, поможет ли это.

Редактировать # 3: Действия по повторению этой проблемы

Создать модель рельсов со столбцом JSONB.Установите аксессоры магазина, которые вам нужны для этого.По умолчанию используется пустой валидатор с использованием валидатора или форматера.Дайте вашей модели ActiveModel :: Dirty включить.Запустите консоль рельсов.выполните следующие команды.Представьте, что user_details - это столбец JSONB, а его метод доступа к хранилищу - names.

  a = Profile.user_details
  a.user_details = { "names" => [{"first_name" => "", "last_name" => "" }] } # This is to replicate what it would look like in a form when a user is submitting a blank entry.
  a.changed # This will show that user_details has changed which is correct
  a.names = []
  a.changed # This will still show that user_details has changed even though it has been set back to its initial state of an empty array. This would work if it was a string field instead of an array.

1 Ответ

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

После открытия проблемы на Rails Github я получил ответ https://github.com/rails/rails/issues/34537#issuecomment-442265161

Изменение принудительно осуществляется через атрибуты для типов атрибутов json, jsonb, hstore и serialized, как мне и сказали.Исходный код здесь: https://github.com/rails/rails/blob/06ab7b27ea1c1ab357085439abacdb464f6742bf/activerecord/lib/active_record/store.rb#L181

Причина, по которой я столкнулся, это то, что я больше не пытаюсь попробовать, так как проект, над которым я работаю, не будет использовать ActiveModel :: Dirty and isnне буду пытаться отслеживать изменения так, как я пытался это сделать.

Так что всем будущим поколениям, которые сталкиваются с этой проблемой, удачи и не стесняйтесь обращаться к этой проблеме github и жаловаться, что это не работает.

...