5

mam dwa modele o następującej strukturze:Rails „assign_attributes” nie przypisując modele zagnieżdżone

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 

Mam testowanie funkcjonalności mojego wniosku z RSpec i zauważyłem coś dziwnego. Jeśli utworzę mieszanie z atrybutami, które nie spełniają kryteriów sprawdzania poprawności mojego zagnieżdżonego modelu (na przykład o zerowym numerze karty), a następnie spróbuję wykonać wywołanie update_attributes, to co otrzymam zwrócone w obiekcie Portfela z nieprawidłową kartą kredytową zagnieżdżony model i odpowiednie błędy. To jest prawidłowe, oczekiwane zachowanie.

Jeśli wezmę tego samego Hash chociaż i uruchomić assign_attributes, a następnie save (co jest to, że update_attributes należy robić, a potem się wrócił nieprawidłowy obiekt Portfel z zupełnie nil zagnieżdżonego obiektu ogóle. Dlaczego? I w jaki sposób można zaktualizować wszystkich zagnieżdżonych wartości atrybutów i sprawdzić błędy bez zapisywania

Odpowiedz

4

Przede wszystkim -?. nie trzeba do include ActiveModel::Validations b bo pochodzą z ActiveRecord::Base.

Po drugie - tak update_attributes używa assign_attributes wewnętrznie, więc zasadniczo powinien działać zgodnie z oczekiwaniami.

Jeśli nie ma żadnego attr_accessible, attr_protected, with/without_protection opcję i zakładam tworzysz właściwego mieszania z

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

to wygląda jak jakiś bug w szynach. Ale jednocześnie sprawdziłem i wygląda na to, że działa dobrze.

wyżej, że jeśli chcesz tylko sprawdzić walidację bez zapisywania obiektu w testach, to wystarczy uruchomić

Wallet.new(hash_with_attributes).valid? 

Należy zwrócić właściwego obiektu portfel z zagnieżdżonego CREDIT_CARD i błędów na nim.

1

To brzmi dla mnie tak, jak Strong Params (funkcja Rails 4) może usuwać zagnieżdżone atrybuty, a ponieważ walidacja nie powiedzie się bez nich, zostaniesz przekierowany z powrotem na stronę edycji z błędami, a twoja karta kredytowa nested_attributes jest teraz zerowa.

Być może to pomoże. https://stackoverflow.com/a/17532811/793330

Również zapisywanie i aktualizacja atrybutów to nie to samo. Zapisz zapisze cały obiekt, podczas gdy aktualizacja zmieni jedynie elementy, które do niego zmieniąsz. Niewielka różnica, ale różnica nie ma znaczenia.

Powiązane problemy