Musisz sprawdzić, czy blok atrybutów zmienił się przed aktualizacją w Railsach 3.
ulica1, ulica2, miasto, stan, kod pocztowy
Wiem, że przydałoby się coś takiego
if @user.street1 != params[:user][:street1]
then do something....
end
Ale ten fragment kodu będzie NAPRAWDĘ długi. Czy istnieje czystszy sposób?
W ten sposób rozwiązałem problem sprawdzania zmian w wielu atrybutach.
changed
Metoda zwraca tablicę atrybutów zmienionych dla tego obiektu.Obie
@user.changed
iattrs
są tablicami, więc mogę uzyskać przecięcie (patrzary & other ary
metoda). Wynikiem przecięcia jest tablica. Wywołującany?
tablicę, otrzymuję wartość true, jeśli istnieje co najmniej jedno przecięcie.Również bardzo przydatna
changed_attributes
metoda zwraca hash atrybutów z ich oryginalnymi wartościami, achanges
zwraca hash atrybutów z ich oryginalnymi i nowymi wartościami (w tablicy).Możesz sprawdzić APIDock, dla których wersje obsługują te metody.
http://apidock.com/rails/ActiveModel/Dirty
źródło
if attrs.any?{|attr| @user.send("#{attr}_changed?")}
gdy chcę sprawdzić, czy zmienił się jeden z kilku różnych atrybutów - oczywiście robię to tylko z atrybutami, które sam zdefiniowałem, ponieważ nie lubię wrzucać parametrów użytkownika dosend
metody. ;)ActiveModel::Dirty
nie zadziałało dla mnie, ponieważ@model.update_attributes()
ukrył zmiany. A więc tak wykryłem zmiany wupdate
metodzie w kontrolerze:Jeśli próbujesz wykryć wiele zmian atrybutów, może to jednak spowodować bałagan. Prawdopodobnie nie powinienem tego robić w kontrolerze, ale ja.
źródło
previous_changes
którym jest również domyślnie dostępny.#update_attributes
nie ukrywa zmian. Zapisuje rekord, więc model jest aktualizowany i nie ma żadnych zmian. Musisz zmienić pole w modelu i sprawdzićchanged?
przed jego zapisaniem. to znaczy. @ model.field = 'foo' lub@model.attributes = @model.attributes.merge(params[:model])
Dla szyn 5.1+ callbacków
Od wersji Ruby on Rails 5.1 metody
attribute_changed?
iattribute_was
ActiveRecord będą przestarzałeUżyj
saved_change_to_attribute?
zamiastattribute_changed?
Więcej przykładów tutaj
źródło
Powyższe odpowiedzi są lepsze, ale dla wiedzy mamy też inne podejście, Zmieniono wartość kolumny 'catagory' dla obiektu (@design),
.Changes zwróci hash z kluczem jako nazwą kolumny i wartościami w postaci tablicy z dwiema wartościami [stara_wartość, nowa_wartość] dla każdej kolumny. Na przykład kategoria powyżej została zmieniona z „ABC” na „XYZ” @design,
Zmiana referencji w ROR
źródło