Rails aktualizuje atrybuty bez zapisywania?
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ę zaktualizować je wszystkie na jednej linii.
4 answers
Wierzę, że to, czego szukasz, to assign_attributes
.
Jest to w zasadzie to samo co update_attributes, ale nie zapisuje rekordu:
class User < ActiveRecord::Base
attr_accessible :name
attr_accessible :name, :is_admin, :as => :admin
end
user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }) # Raises an ActiveModel::MassAssignmentSecurity::Error
user.assign_attributes({ :name => 'Bob'})
user.name # => "Bob"
user.is_admin? # => false
user.new_record? # => true
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-10 16:08:26
Możesz użyć assign_attributes
LUB attributes=
(są takie same)
Ściągawka metod aktualizacji (dla Rails 4):
-
update_attributes
=assign_attributes
+save
-
attributes=
= aliasassign_attributes
-
update
= aliasupdate_attributes
Source:
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
Kolejny oszust sheet:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-07 13:47:16
Możesz użyć metody 'attributes':
@car.attributes = {:model => 'Sierra', :years => '1990', :looks => 'Sexy'}
Ź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 hash z kluczami pasującymi do nazw atrybutów (które ponownie pasują do nazw kolumn).
Jeśli guard_protected_attributes jest prawdziwe( domyślne), wtedy wrażliwe atrybuty mogą być chronione z tej postaci przypisanie masy przy użyciu makra attr_protected. Można też alternatywnie określić, do których atrybutów można uzyskać dostęp za pomocą makra attr_accessible. Wtedy wszystkie atrybuty nie zawarte w tym nie będą mogły być przypisane masowo.
class User < ActiveRecord::Base
attr_protected :is_admin
end
user = User.new
user.attributes = { :username => 'Phusion', :is_admin => true }
user.username # => "Phusion"
user.is_admin? # => false
user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
user.is_admin? # => true
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 14:58:24
Do masowego przypisywania wartości do modelu ActiveRecord bez zapisywania, użyj metod assign_attributes
lub attributes=
. Metody te są dostępne w Rails 3 i nowszych. Jednak istnieją niewielkie różnice i związane z wersją gotchas należy pamiętać.
Obie metody podążają za tym użyciem:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }
@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }
Zauważ, że żadna z metod nie wykona walidacji ani nie wykona wywołań zwrotnych; wywołanie zwrotne i Walidacja nastąpi po wywołaniu save
.
Rails 3
attributes=
różni się nieco z assign_attributes
w Rails 3. attributes=
sprawdzi, czy przekazany do niego argument jest Hashem i zwróci natychmiast, jeśli nim nie jest; assign_attributes
nie ma takiego Hash check. Zapoznaj się z dokumentacją API przypisywania atrybutów ActiveRecord attributes=
.
Następujący nieprawidłowy kod po cichu zawiedzie, po prostu zwracając bez ustawiania atrybutów:
@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]
attributes=
będzie cicho zachowywać się tak, jakby zadania zostały wykonane pomyślnie, podczas gdy naprawdę, nie były.
To nieprawidłowy kod wywoła wyjątek, gdy assign_attributes
spróbuje zsynchronizować klucze hashujące tablicy:
@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])
assign_attributes
wywoła wyjątek NoMethodError
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 wyjątek występuje, jest bardzo ważny.
Jedyną różnicą między tymi przypadkami jest metoda zastosowana do przypisania masy: attributes=
po cichu udaje się, a assign_attributes
wyświetla 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 API, lub nawet po prostu używając serii transformacji danych i zapominając o Hash[]
wynikach końcowego .map
. Zachowaj trochę kodu 50 linii powyżej i 3 Funkcje usunięte z przypisania atrybutów, a masz przepis na awarię.
Lekcja z Rails 3 jest taka: zawsze używaj assign_attributes
zamiast attributes=
.
Rails 4
W Rails 4, attributes=
jest po prostu aliasem do assign_attributes
. Zapoznaj się z dokumentacją API przypisywania atrybutów ActiveRecord attributes=
.
W przypadku Rails 4, każda z metod może być używana zamiennie. Nie podanie Hasha 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 wykonywania zadań przed lotem do save
, możesz być interesuje się również walidacją przed zapisem. Możesz do tego użyć 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żywać w ten sposób:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?
Daje to możliwość obsługi wszelkich problemów z walidacją przed wywołaniem save
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-17 15:16:01