Używam Rails3, ActiveRecord
Zastanawiam się tylko, jak połączyć zakresy za pomocą instrukcji OR zamiast AND.
na przykład
Person.where(:name => "John").where(:lastname => "Smith")
To zwykle zwraca:
name = 'John' AND lastname = 'Smith'
ale chciałbym:
`name = 'John' OR lastname = 'Smith'
Odpowiedzi:
Ty byś zrobił
W tej chwili nie ma żadnego innego wsparcia OR przez nową składnię AR3 (to znaczy bez użycia klejnotów innych firm).
źródło
.or
wbudowane .Zgodnie z tym żądaniem pull , Rails 5 obsługuje teraz następującą składnię dla zapytań łańcuchowych:
Istnieje również przeniesienie funkcjonalności do Rails 4.2 za pośrednictwem tego klejnotu.
źródło
Użyj ARel
źródło
Wystarczy opublikować składnię Array dla tych samych zapytań w kolumnie LUB, aby pomóc im się zorientować.
źródło
Aktualizacja dla Rails4
nie wymaga żadnych klejnotów stron trzecich
Stara odpowiedź
nie wymaga żadnych klejnotów stron trzecich
źródło
or
lub innych operatorów w bloku tekstowym, z których żaden nie jest odzwierciedlony w kodzie OP....where_values.join(' OR ')
w moim przypadku.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
część, jeśli twoje zakresy nie mają żadnych zmiennych, które wymagają powiązania.Możesz także użyć MetaWhere gem, aby nie mylić kodu z elementami SQL:
źródło
Jeśli ktoś szuka zaktualizowanej odpowiedzi na to, wygląda na to, że istnieje żądanie ściągnięcia, aby pobrać to do Rails: https://github.com/rails/rails/pull/9052 .
Dzięki małpiej łatce @ j-mcnally dla ActiveRecord ( https://gist.github.com/j-mcnally/250eaaceef234dd8971b ) możesz wykonać następujące czynności:
Jeszcze cenniejsza jest możliwość łączenia lunet z
OR
:Następnie możesz znaleźć wszystkie osoby z imieniem lub nazwiskiem lub których rodzic ma nazwisko
Nie jest to najlepszy przykład użycia tego, ale po prostu próba dopasowania go do pytania.
źródło
.or
funkcjonalności łańcucha. Udało mi się użyć małpy łatki, o której wspomniałem na Railsach> = 3.2; jednakże możesz chcieć poczekać, aż Rails 5 wprowadzi jakiekolwiek długotrwałe zmiany do twojego kodu.U mnie (Rails 4.2.5) działa tylko tak:
źródło
Byłby to dobry kandydat na MetaWhere, jeśli używasz Rails 3.0+, ale nie działa na Railsach 3.1. Zamiast tego możesz wypróbować squeel . Jest zrobiony przez tego samego autora. Oto, jak wykonałbyś łańcuch oparty na LUB:
Możesz łączyć i dopasowywać ORAZ / LUB, pośród wielu innych niesamowitych rzeczy .
źródło
Zaktualizowana wersja Rails / ActiveRecord może obsługiwać tę składnię natywnie. Wyglądałoby to podobnie do:
Jak wspomniano w tym żądaniu ściągnięcia https://github.com/rails/rails/pull/9052
Na razie po prostu trzymanie się następujących działa świetnie:
źródło
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
nie działa. Powinien to być Foo.where (foo: 'bar1'). Or.where (Foo.where (bar: 'bar2'))Szyny 4 + luneta + arel
Próbowałem łączyć nazwane zakresy z .or i bez powodzenia, ale to działało w przypadku znalezienia czegokolwiek z ustawionymi parametrami logicznymi. Generuje SQL jak
źródło
Szyny 4
źródło
Jeśli chcesz podać zakres (zamiast pracować jawnie na całym zbiorze danych), oto co powinieneś zrobić z Railsami 5:
Lub:
źródło
Jeśli nie możesz ręcznie napisać klauzuli where zawierającej instrukcję „lub” (tj. Chcesz połączyć dwa zakresy), możesz użyć union:
(źródło: ActiveRecord Query Union )
To zwróci wszystkie rekordy pasujące do dowolnego zapytania. Jednak zwraca to tablicę, a nie arel. Jeśli naprawdę chcesz zwrócić arel, przejdź do tego streszczenia: https://gist.github.com/j-mcnally/250eaaceef234dd8971b .
To wystarczy, o ile nie masz nic przeciwko łataniu szyn małp.
źródło
Zobacz także te powiązane pytania: tutaj , tutaj i tutaj
Dla szyn 4, na podstawie tego artykułu i tej oryginalnej odpowiedzi
Zwróć uwagę na uwagę artykułu na końcu:
źródło
To bardzo wygodny sposób, który działa dobrze w Railsach 5:
źródło
squeel
gem zapewnia niezwykle łatwą drogę do osiągnięcia tego celu (przed tym Kiedyś coś takiego sposobu @ coloradoblue'S):źródło
Tak więc odpowiedź na pierwotne pytanie, czy możesz połączyć zakresy za pomocą 'lub' zamiast 'i' wydaje się brzmieć „nie, nie możesz”. Możesz jednak ręcznie zakodować zupełnie inny zakres lub zapytanie, które wykona zadanie, lub użyć innego frameworka niż ActiveRecord, np. MetaWhere lub Squeel. Nie przydatne w moim przypadku
Ja 'or'ing zakres wygenerowany przez pg_search, który robi trochę więcej niż select, zawiera porządek przez ASC, co powoduje bałagan w czystej unii. Chcę 'lub' z ręcznie wykonanym teleskopem, który robi rzeczy, których nie mogę zrobić w pg_search. Więc musiałem to zrobić w ten sposób.
To znaczy zamień zakresy na sql, umieść nawiasy wokół każdego z nich, połącz je razem, a następnie znajdź_by_sql za pomocą wygenerowanego sql. To trochę bzdury, ale działa.
Nie, nie mów mi, że mogę użyć „against: [: name,: code]” w pg_search, chciałbym to zrobić w ten sposób, ale pole „name” to hstore, którego pg_search nie może obsłużyć jeszcze. Dlatego zakres według nazwy musi zostać utworzony ręcznie, a następnie połączony z zakresem pg_search.
źródło
źródło