5

У меня есть две модели со следующей структурой:Rails «assign_attributes» не назначая вложенные модели

class Wallet < ActiveRecord::Base 
    include ActiveModel::Validations 
    has_one :credit_card 
    accepts_nested_attributes_for :credit_card 

    validates :credit_card, :presence => true 
    validates_associated :credit_card 
    ... 
end 

class CreditCard < ActiveRecord::Base 
    include ActiveModel::Validations 
    belongs_to :wallet 

    validates :card_number, :presence => true 
    validates :expiration_date, :presence => true 
    ... 
end 

Я тестирование функциональности моего приложения с RSpec, и я заметил что-то странное. Если я создаю хэш с атрибутами, которые не соответствуют критериям проверки моей вложенной модели (например, с номером nil card_number), а затем попытайтесь выполнить вызов update_attributes, то то, что я получаю в кошельке с недействительной кредитной картой вложенной модели и соответствующих ошибок. Это правильное, ожидаемое поведение.

Если взять то же Hash, хотя и запустить assign_attributes, а затем save (это все, что update_attributes должен делать, то я получаю возвратил недействительный объект Wallet с полностью нулевым вложенным объектом. Почему? И как может Я обновляю все значения вложенных атрибутов и проверить на наличие ошибок без сохранения

ответ

4

Прежде всего -. Вам не нужно include ActiveModel::Validations б потому что у них есть ActiveRecord::Base.

Второй - да update_attributes использует assign_attributes внутренне, поэтому он должен работать должным образом.

Если вы не имеете attr_accessible, attr_protected, with/without_protection варианта, и я предполагаю, что вы создаете правильный хэш с

{'credit_card_attributes' => {'card_number' => ''}} 

, то это выглядит как какое-то ошибка в рельсах. Но в то же время я просто проверил его, и кажется, что он работает нормально.

Выше, что если вы хотите просто проверить валидации без сохранения объекта в тестах, а затем просто запустить

Wallet.new(hash_with_attributes).valid? 

Он должен вернуть надлежащий объект кошелька с вложенной CREDIT_CARD и ошибками на нем.

0

Как я понимаю, assign_attributes пропускает проверку безопасности

In Rails 3, is there a difference between = and assign_attributes?

+0

Эта ссылка, кажется, говорит обратное (что знак равенства - это функция, которая пропускает проверки безопасности). И я не понимаю, почему это приведет к поведению, которое я вижу. – Bryce

1

Мне кажется, что Strong Params (функция Rails 4) может удалять вложенные атрибуты, и поскольку ваша проверка не удалась без них, вы снова перенаправляетесь на страницу редактирования с ошибками, а ваша кредитная карта nested_attributes теперь равна нулю.

Возможно, это поможет. https://stackoverflow.com/a/17532811/793330

Также сохранять и обновлять атрибуты не одно и то же. Сохранить сохранит весь объект, тогда как обновление изменит только те элементы, которые вы перешли на него, которые изменились. Небольшая разница, но разница не имеет значения.

Смежные вопросы