W przypadku railsów, jak mogę się dowiedzieć, co spowodowało awarię .save (), inne niż błędy walidacji?

91

Mam model ActiveRecord, który wraca truez valid?(i .errors jest pusty), ale wraca falsez save(). Jeśli instancja modelu jest prawidłowa, jak mogę dowiedzieć się, co powoduje niepowodzenie zapisu?

kdt
źródło
7
Miałem ten problem kilka tygodni temu. Niektóre refaktoryzacje pozostawiły funkcję before_save zwracającą przez cały czas false, co powoduje niepowodzenie zapisywania.
Jeff Paquette,
1
@Jeff - dzięki, okazuje się, że była metoda: before_save zwracająca false. Jak się dowiedziałeś? Czy to była tylko inspekcja kodu?
kdt
To była inspekcja kodu i robienie różnic z kontrolą wersji.
Jeff Paquette,

Odpowiedzi:

49

Sprawdź wszystkie swoje oddzwonienia.

Miałem taki problem, gdy miałem i metodę „after_validate”, która zawodziła po wprowadzeniu wielu zmian w modelu. Model był prawidłowy, ale "after_validate" zwracał fałsz, więc jeśli użyłem model.validgo, powiedziałem prawdę, ale jeśli go zapisałem, dostałem błędy walidacji (przekazane z wywołania zwrotnego after_validate). To było dziwne.

Spójrz na ślad aplikacji, a powinieneś być w stanie zobaczyć, który wiersz kodu zgłasza wyjątek.

Andrzej
źródło
2
Zgodnie z komentarzem Jeffa, problem okazał się być wywołaniem zwrotnym before_save zwracającym false.
kdt
3
@kdt - na tym właśnie polegał mój problem. Nie myślałem o tym, ponieważ before_save miało po prostu ustawić właściwość, ale ponieważ ustawiało ją na fałszywą wartość, która została niejawnie zwrócona i sprawiła, że ​​zapisywanie nie powiodło się. Z drugiej strony mam teraz możliwość naprawienia tego kodu poprzez dodanie linii "Hey! That's MY fake leg!" # Believe it or not, this is important. Nie żebym to zrobił. ;)
Nathan Long
2
Dobrym sposobem na zapewnienie prawdziwej wartości zwracanej jesttrue.tap { do_something }
Nathan Long
wow, co za niejasny problem. Nigdy nie zgadłby, że wywołanie zwrotne zwracające fałsz przestałoby zapisywać. Czy ktoś mógłby wskazać mi dokumentację na ten temat? Dzięki za zwrócenie uwagi!
andy
1
@andy Guides.rubyonrails.org/…
Andrzej
116

Spróbuj użyć wersji save!z hukiem (z wykrzyknikiem na końcu) i sprawdź wynikowy błąd.

Andy Lindeman
źródło
4
zapisać! po prostu wyrzuca RecordNotSaved (kiedy drukuję .message o wyjątku, otrzymuję tylko nazwę klasy wyjątku). Czy jest miejsce, w którym powinienem szukać więcej szczegółów?
kdt
1
Jeśli jesteś w trybie programowania Railsów, powinien on wypisać pełny opis błędu wraz ze śladem stosu. Zajrzyj tam, aby znaleźć wskazówki i / lub opublikuj je tutaj.
Andy Lindeman
1
Używam konsoli, ładuję obiekt (np. O = Object.find #id), a następnie robię o.save! jak mówi odpowiedź. Wyświetla, dlaczego nie zapisuje.
pduey
1
FYI, call save!może podnieść ActiveRecord::RecordInvalid(ponieważ uruchamia walidację), a ActiveRecord::RecordNotSavedwięc to jest to, co chcesz uratować.
Dennis
2
+1, ponieważ jest to najmniej niezadowalająca odpowiedź na fundamentalne pytanie, jak diagnozować .saveniepowodzenia, które nie są spowodowane walidacją. Określenie „najmniej niezadowalające” odnosi się do Railsów, a nie do tej odpowiedzi.
Chuck Batson
112

Jeśli @user.save(na przykład) zwraca false, po prostu uruchom to, aby uzyskać wszystkie błędy:

@user.errors.full_messages
Sam Alex
źródło
13
Jak wspomniałem w pytaniu, .valid? jest prawdą - tj. nie ma błędów walidacji. Sprawdziłem, że .errors zwraca również pustą listę (zaktualizowałem pytanie, aby to wskazać)
kdt
3

Tak, rozwiązałem ten problem, upewniając się, że zwracam wartość true we wszystkich moich wywołaniach zwrotnych before_ *, a następnie zaczyna działać :)

Pencilcheck
źródło
-1

Problem polegał na tym, że zapomniałem dodać walidację do modelu.

class ContactGroup < ActiveRecord::Base
  validates_presence_of :name
end
Ian Vaughan
źródło