Kiedy mam tablicę identyfikatorów, na przykład
ids = [2,3,5]
i występuję
Comment.find(ids)
wszystko dziala. Ale jeśli istnieje identyfikator, który nie istnieje, pojawia się wyjątek. Dzieje się tak zwykle, gdy otrzymuję listę identyfikatorów pasujących do jakiegoś filtra, a potem robię coś podobnego
current_user.comments.find(ids)
Tym razem mogę mieć ważny identyfikator komentarza, który jednak nie należy do danego użytkownika, więc nie został znaleziony i pojawia się wyjątek.
Próbowałem find(:all, ids)
, ale zwraca wszystkie rekordy.
Jedyny sposób, w jaki mogę to teraz zrobić, to
current_user.comments.select { |c| ids.include?(c.id) }
Ale wydaje mi się, że to super nieefektywne rozwiązanie.
Czy istnieje lepszy sposób na wybranie identyfikatora w tablicy bez uzyskiwania wyjątku dla nieistniejącego rekordu?
źródło
Array
zamiast anActiveRecord::Relation
, co ogranicza to, co możesz później z nim zrobić.Comment.where(id: [2, 3, 5])
zwraca plikActiveRecord::Relation
.Aktualizacja: Ta odpowiedź jest bardziej odpowiednia dla Rails 4.x
Zrób to:
Silniejszą stroną tego podejścia jest to, że zwraca
Relation
obiekt, do którego można dołączyć więcej.where
klauzul,.limit
klauzul itp., Co jest bardzo pomocne. Pozwala również na nieistniejące identyfikatory bez rzucania wyjątków.Nowsza składnia Rubiego wyglądałaby tak:
źródło
where
składni podczas porównywania z tablicą. Pomyślałem, że być może będę musiał zakodować SQL za pomocąIN
instrukcji, ale wygląda to bardziej przejrzysto i jest łatwym zamiennikiem dla przestarzałegoscoped_by_id
.Jeśli potrzebujesz większej kontroli (być może musisz podać nazwę tabeli), możesz również wykonać następujące czynności:
źródło
your_id_array
której odzyskasz przedmioty?ORDER BY
nie zadziała w mojej sytuacji, ponieważ kolejność nie jest oparta na atrybucie. Jest jednak sposób na zrobienie tego przez SQL (więc jest szybki) i ktoś nawet stworzył dla niego klejnot. Sprawdź te pytania i odpowiedzi: stackoverflow.com/questions/801824/…Teraz metody .find i .find_by_id są przestarzałe w railsach 4. Zamiast tego możemy użyć poniżej:
Będzie działać, nawet jeśli niektóre identyfikatory nie istnieją. Działa to w
Również do wykluczania identyfikatorów
źródło
Aby uniknąć wyjątków zabijających Twoją aplikację, powinieneś je złapać i traktować tak, jak chcesz, definiując zachowanie aplikacji w sytuacjach, w których nie znaleziono identyfikatora.
Oto więcej informacji na temat wyjątków w języku Ruby.
źródło
Możesz go również użyć w named_scope, jeśli chcesz umieścić tam inne warunki
na przykład dołącz inny model:
źródło