Próbuję znaleźć wszystkich użytkowników o identyfikatorze większym niż 200, ale mam problem z określoną składnią.
User.where(:id > 200)
i
User.where("? > 200", :id)
obaj zawiedli.
Jakieś sugestie?
ruby-on-rails
syntax
where
Adam Templeton
źródło
źródło
?
zamiast wstawiania200
?Testowałem to tylko w Railsach 4, ale jest ciekawy sposób na użycie zakresu z
where
hashem, aby uzyskać takie zachowanie.wygeneruje SQL
To samo można zrobić za mniej niż za pomocą
-Float::INFINITY
.Właśnie opublikowałem podobne pytanie z pytaniem o zrobienie tego z datami tutaj na SO .
>=
vs>
Aby ludzie nie musieli przekopywać się i śledzić rozmowy z komentarzami, oto najważniejsze informacje.
Powyższa metoda generuje tylko
>=
zapytanie, a nie plik>
. Istnieje wiele sposobów radzenia sobie z tą alternatywą.Dla liczb dyskretnych
Możesz użyć
number_you_want + 1
strategii takiej jak powyżej, w której jestem zainteresowany użytkownikami,id > 200
ale faktycznie ich szukamid >= 201
. Jest to dobre w przypadku liczb całkowitych i liczb, w przypadku których można zwiększyć o jedną jednostkę zainteresowania.Jeśli masz wyodrębnioną liczbę do dobrze nazwanej stałej, może to być najłatwiejsze do odczytania i zrozumienia na pierwszy rzut oka.
Logika odwrócona
Możemy wykorzystać fakt, że
x > y == !(x <= y)
i użyć łańcucha gdzie nie.który generuje SQL
Przeczytanie i uzasadnienie zajmie dodatkową sekundę, ale będzie działać dla wartości niedyskretnych lub kolumn, w których nie można użyć
+ 1
strategii.Stół Arel
Jeśli chcesz uzyskać fantazję, możesz skorzystać z
Arel::Table
.wygeneruje SQL
Szczegóły są następujące:
To podejście pozwoli Ci uzyskać dokładnie ten SQL, który Cię interesuje, jednak niewiele osób używa bezpośrednio tabeli Arel i może uznać ją za nieporządną i / lub mylącą. Ty i Twój zespół będziecie wiedzieć, co jest dla Ciebie najlepsze.
Premia
Począwszy od Rails 5 możesz to również zrobić z datami!
wygeneruje SQL
Podwójny bonus
Po wydaniu Ruby 2.6 (25 grudnia 2018 r.) Będziesz mógł używać nowej składni nieskończonego zakresu! Zamiast tego
201..Float::INFINITY
będziesz mógł po prostu pisać201..
. Więcej informacji w tym poście na blogu .źródło
where
dopasowań. Bo>
proponuję użyć>= (number_you_want + 1)
dla uproszczenia. Jeśli naprawdę chcesz mieć pewność, że jest to tylko>
zapytanie, możesz uzyskać dostęp do tabeli ARel. Każda klasa dziedzicząca poActiveRecord
maarel_table
metodę pobierającą, która zwraca wartośćArel::Table
dla tej klasy. Dostęp do kolumn w tabeli uzyskuje się za pomocą[]
metodyUser.arel_table[:id]
. W ten sposóbArel::Attributes::Attribute
możesz zadzwonićgt
i przekazać200
. Można to następnie przekazaćwhere
. npUser.where(User.arel_table[:id].gt(200))
.User.where(created_at: 3.days.ago..DateTime::Infinity.new)
.WHERE (users.created_at >= '2016-04-09 14:31:15' AND users.created_at < #<Date::Infinity:0x00>)
(wsteczne tiki wokół nazw tabel i kolumn pominięte przy formatowaniu komentarzy SO).Lepszym zastosowaniem jest utworzenie zakresu w modelu użytkownika
where(arel_table[:id].gt(id))
źródło
Jeśli chcesz bardziej intuicyjnego pisania, istnieje klejnot zwany squeel , który pozwoli ci napisać instrukcje w następujący sposób:
Zwróć uwagę na znaki „nawiasów klamrowych” {} i
id
będące tylko tekstem.Wszystko, co musisz zrobić, to dodać squeel do swojego Gemfile:
Może to znacznie ułatwić życie podczas pisania złożonych instrukcji SQL w języku Ruby.
źródło
Arel to twój przyjaciel.
źródło
Inną ciekawą możliwością jest ...
Ta funkcja pozwala tworzyć bardziej zrozumiałe zapytania, jeśli chcesz zamienić w wielu miejscach, na przykład ...
Ma to większe znaczenie niż dużo
?
w zapytaniu ...źródło
Często mam ten problem z polami dat (gdzie operatory porównania są bardzo powszechne).
Aby rozwinąć dalej odpowiedź Mihai, która moim zdaniem jest solidnym podejściem.
Do modeli możesz dodać takie zakresy:
... a następnie w kontrolerze lub gdziekolwiek używasz swojego modelu:
... bardziej złożony przykład z łączeniami wygląda następująco:
Ogromną zaletą tego podejścia jest (a) możliwość komponowania zapytań z różnych zakresów oraz (b) uniknięcie kolizji aliasów przy dwukrotnym dołączaniu do tej samej tabeli, ponieważ arel_table będzie obsługiwać tę część generowania zapytania.
źródło
Rails 6.1+
Railsy 6.1 dodały nową „składnię” dla operatorów porównania w
where
warunkach, na przykład:Twoje zapytanie można więc przepisać w następujący sposób:
Oto link do PR, gdzie można znaleźć więcej przykładów.
źródło
Krótszy:
źródło
where("id > ?", 200)
składnia). To nie pozwala na osiągnięcie tego.