W moim obecnym programie railsowym używam czegoś takiego jak
user = User.find(10)
Gdy nie ma użytkownika o ID = 10, będę miał wyjątek taki jak:
ActiveRecord::RecordNotFound: Couldn't find User with ID=10
Czy mogę uzyskać zero zamiast zgłaszać wyjątek, więc kiedy robię coś takiego:
unless user = Challenge.find(10)
puts "some error msg"
end
Chcę tylko uzyskać zero, gdy nie ma rekordów i nie chcę używać rozpoczynania / ratowania
Dzięki
Odpowiedzi:
Tak, po prostu zrób:
Dla szyn 4 i 5:
źródło
.find_by_*
że zwróci zero, a.find
nie.Something.find_by(id: x)
utworzyłoby się instrukcję SQL ze wszystkimi parami atrybut / wartość hasha jako część klauzuli WHERE. Dla mnie wygląda na błąd w Railsach.find_by_...
wyszukiwarki dla każdego atrybutu, który zawiera model:id
.Challenge.find_by_id(10)
Powinien więc działać niezależnie od wersji Railsów.Challenge.find(10) rescue nil
W Railsach 4, dynamiczne wyszukiwarki - takie jak
find_by_id
użyte w zaakceptowanej odpowiedzi - zostały wycofane.Idąc dalej, powinieneś użyć nowej składni:
źródło
Challenge.find_by(id: 10)
jest inny sposób pisania tegomożesz to zrobić trochę hakersko, po prostu użyj interfejsu zapytań ActiveRecord.
zwróci to zero, zamiast zgłosić wyjątek
źródło
find_by_id
dlatego, że jest przenośny z Rails 3 do 4. W Rails 4 jestfind_by(:id => 10)
.Dlaczego po prostu nie złapiesz wyjątku? Twoja sprawa wygląda dokładnie tak, jak zostały stworzone wyjątki:
Jeśli chcesz naprawić błąd w bloku ratunkowym (np. Ustawiając użytkownika zastępczego (wzorzec null)), możesz kontynuować pracę z kodem poniżej tego bloku. W przeciwnym razie możesz po prostu umieścić cały kod „szczęśliwego przypadku” w bloku między „begin” i „rescue”.
źródło
begin…end
bloku, jeśli masz już blok, taki jak metoda kontrolera. W takim przypadku jedyną dodatkową linią, której potrzebujesz, jestrescue
linia. O wiele bardziej eleganckie i łatwiejsze w obsłudze niż sprawdzanie zanil
pomocąif
oświadczenia.Możesz tego spróbować
Challenge.exists?(10)
źródło
Dla tych, którzy walczą z mangusty , okazuje się, że obie
find
ifind_by
metody będą stanowić wyjątek - bez względu na wersję railsową !Istnieje opcja (mianowicie raise_not_found_error ), która może być ustawiona na false, ale gdy falsey sprawia, że
find
metoda również nie zgłasza wyjątku.Tak więc rozwiązaniem dla użytkowników mongoidów jest obrzydliwy kod:
źródło
.where(email: params[:email]).first
dla mnie.rescue
składni, ponieważ może ona ukryć problemy, takie jak literówkitak proste, jak:
źródło
if user...else
Możesz użyć find_by z wymaganym atrybutem (w twoim przypadku id), to zwróci nil zamiast dawać błąd, jeśli podany id nie zostanie znaleziony.
lub możesz użyć nowego formatu:
Możesz również użyć gdzie, ale musisz wiedzieć, że jeśli zwracasz relację rekordu aktywnego z zerem lub większą liczbą rekordów, musisz najpierw użyć, aby zwrócić tylko jeden rekord lub zero w przypadku, gdy nie zwrócą żadnych rekordów.
źródło