Czy istnieje alternatywa dla update_attributes, która nie zapisuje rekordu?
Więc mógłbym zrobić coś takiego:
@car = Car.new(:make => 'GMC')
#other processing
@car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it")
#other processing
@car.save
BTW, wiem, że mogę @car.model = 'Sierra'
, ale chcę je wszystkie zaktualizować w jednym wierszu.
assign_attributes
apidock.com/rails/ActiveRecord/Base/assign_attributesOdpowiedzi:
Wierzę, że to, czego szukasz
assign_attributes
.Jest to w zasadzie to samo, co update_attributes, ale nie zapisuje rekordu:
źródło
attr_accessible :is_admin, :as => :admin
:;)attr_protected :is_admin
. Lub:attr_accessible :name
Chodzi o to, że w tym przykładzie: is_admin jest chroniony. Powinienem również zauważyć, że próba masowego przypisania chronionego atrybutu.assign_attributes
rzeczywiście podnosi wartośćActiveModel::MassAssignmentSecurity::Error
, nawet jeśli nie pokazano tego w przykładzie.user.assign_attributes({ :name => 'Josh', :is_admin => true })
wywołuje komunikat o błędzie i nie ustawia właściwości nazwy użytkownika.Możesz użyć
assign_attributes
lubattributes=
(są takie same)Zaktualizuj ściągawki metod (dla Rails 6):
update
=assign_attributes
+save
attributes=
= aliasassign_attributes
update_attributes
= przestarzałe, aliasupdate
Źródło:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment .rb
Kolejna ściągawka:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet
źródło
Możesz użyć metody „atrybuty”:
Źródło: http://api.rubyonrails.org/classes/ActiveRecord/Base.html
atrybuty = (new_attributes, guard_protected_attributes = true) Pozwala ustawić wszystkie atrybuty na raz, przekazując skrót z kluczami pasującymi do nazw atrybutów (które ponownie pasują do nazw kolumn).
Jeśli wartość guard_protected_attributes ma wartość true (wartość domyślna), wówczas wrażliwe atrybuty można zabezpieczyć przed tą formą przypisywania masy za pomocą makra attr_protected. Lub możesz alternatywnie określić, do których atrybutów można uzyskać dostęp za pomocą makra attr_accessible. Wówczas wszystkie atrybuty, które nie są w nim uwzględnione, nie będą mogły być przypisywane masowo.
źródło
Do masowego przypisywania wartości do modelu ActiveRecord bez zapisywania należy użyć metody
assign_attributes
lubattributes=
. 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:
Zauważ, że żadna z metod nie przeprowadzi walidacji ani nie wykona wywołań zwrotnych; oddzwanianie i sprawdzanie poprawności nastąpi, gdy
save
wywołaniu.Szyny 3
attributes=
różni się nieznacznie od tegoassign_attributes
w Rails 3.attributes=
sprawdzi, czy przekazany mu argument to Hash, i natychmiast zwróci, jeśli nie jest;assign_attributes
nie 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:
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_attributes
spróbuje skreślić klucze skrótu w otaczającej tablicy:assign_attributes
zgłosiNoMethodError
wyjątek dlastringify_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ę iassign_attributes
podnosi 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_attributes
zamiastattributes=
.Szyny 4
W Rails 4
attributes=
jest po prostu aliasem doassign_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 metodvalid?
iinvalid?
. 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:Umożliwi to obsługę wszelkich problemów związanych z weryfikacją przed rozmową telefoniczną
save
.źródło