Do masowego przypisywania wartości do modelu ActiveRecord bez zapisywania należy użyć metody assign_attributeslub attributes=. Te metody są dostępne w Rails 3 i nowszych. Istnieją jednak niewielkie różnice i problemy związane z wersją, o których należy pamiętać.
Obie metody wykorzystują to użycie:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }
@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }
Zauważ, że żadna z metod nie przeprowadzi walidacji ani nie wykona wywołań zwrotnych; oddzwanianie i sprawdzanie poprawności nastąpi, gdysave wywołaniu.
Szyny 3
attributes=różni się nieznacznie od tego assign_attributesw Rails 3. attributes=sprawdzi, czy przekazany mu argument to Hash, i natychmiast zwróci, jeśli nie jest; assign_attributesnie ma takiego testu mieszania. Zobacz dokumentację interfejsu API przypisywania atrybutów ActiveRecord dlaattributes= .
Poniższy nieprawidłowy kod po cichu zakończy się niepowodzeniem, po prostu powróci bez ustawiania atrybutów:
@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]
attributes= będą po cichu zachowywać się tak, jakby zadania zostały wykonane pomyślnie, a tak naprawdę nie były.
Ten nieprawidłowy kod zgłosi wyjątek, gdy assign_attributesspróbuje skreślić klucze skrótu w otaczającej tablicy:
@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])
assign_attributeszgłosi NoMethodErrorwyjątek dla stringify_keys, wskazując, że pierwszy argument nie jest skrótem. Sam wyjątek nie jest bardzo pouczający o rzeczywistej przyczynie, ale fakt, że występuje wyjątek, jest bardzo istotny ważny.
Jedyną różnicą między tymi przypadkami jest metoda zastosowana do przypisania masy: attributes=po cichu udaje się i assign_attributespodnosi wyjątek informujący o wystąpieniu błędu.
Te przykłady mogą wydawać się wymyślone i są do pewnego stopnia, ale ten typ błędu może łatwo wystąpić podczas konwersji danych z interfejsu API lub nawet po prostu przy użyciu serii transformacji danych i zapominania o Hash[]wynikach końcowych .map. Utrzymaj 50 linii kodu powyżej i 3 funkcje usunięte z przypisania atrybutu, a masz przepis na niepowodzenie.
Lekcja z Rails 3 jest taka: zawsze używaj assign_attributeszamiast attributes=.
Szyny 4
W Rails 4 attributes=jest po prostu aliasem do assign_attributes. Zobacz dokumentację interfejsu API przypisywania atrybutów ActiveRecord dlaattributes= .
W przypadku Rails 4 każdą metodę można stosować zamiennie. Niepowodzenie przekazania skrótu jako pierwszego argumentu spowoduje bardzo pomocny wyjątek:ArgumentError: When assigning attributes, you must pass a hash as an argument.
Walidacje
Jeśli przygotowujesz się do lotu przed przygotowaniem do save, możesz również chcieć sprawdzić poprawność przed zapisaniem. Możesz użyć do tego metod valid?i invalid?. Obie zwracają wartości logiczne. valid?zwraca true, jeśli niezapisany model przejdzie wszystkie walidacje, lub false, jeśli nie. invalid?jest po prostu odwrotnościąvalid?
valid? można użyć w następujący sposób:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?
Umożliwi to obsługę wszelkich problemów związanych z weryfikacją przed rozmową telefoniczną save.