Jak wykonać zapytanie OR w Rails 3 ActiveRecord. Wszystkie znalezione przykłady mają tylko zapytania ORAZ.
Metoda Edit: OR jest dostępna od Railsów 5. Zobacz ActiveRecord :: QueryMethods
ruby-on-rails
ruby-on-rails-3
rails-activerecord
pho3nixf1re
źródło
źródło
Post.where(column: 'something').or(Post.where(other: 'else'))
Odpowiedzi:
Użyj ARel
t = Post.arel_table results = Post.where( t[:author].eq("Someone"). or(t[:title].matches("%something%")) )
Wynikowy kod SQL:
ree-1.8.7-2010.02 > puts Post.where(t[:author].eq("Someone").or(t[:title].matches("%something%"))).to_sql SELECT "posts".* FROM "posts" WHERE (("posts"."author" = 'Someone' OR "posts"."title" LIKE '%something%'))
źródło
matches
wyprodukujeLIKE
dla sqlite (domyślnie niewrażliwa na wielkość liter) iILIKE
na postgres (wymaga jawnego niewrażliwości na wielkość liter, jak operator).Jeśli chcesz użyć operatora OR na wartości jednej kolumny, możesz przekazać tablicę do,
.where
a ActiveRecord użyjeIN(value,other_value)
:Model.where(:column => ["value", "other_value"]
wyjścia:
SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value')
Powinno to osiągnąć równowartość w
OR
jednej kolumnieźródło
w Railsach 3 powinno być
Model.where("column = ? or other_column = ?", value, other_value)
Obejmuje to również surowy sql, ale nie sądzę, aby w ActiveRecord był sposób na wykonanie operacji OR. Twoje pytanie nie jest pytaniem noobowym.
źródło
Page.where("pages.column = ? or pages.other_column = ?", value, other_value)
Zaktualizowana wersja Rails / ActiveRecord może obsługiwać tę składnię natywnie. Wyglądałoby to podobnie do:
Foo.where(foo: 'bar').or.where(bar: 'bar')
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:
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
Aktualizacja: Według https://github.com/rails/rails/pull/16052
or
funkcja będzie dostępna w Rails 5Aktualizacja: Funkcja została włączona do gałęzi Rails 5
źródło
or
jest teraz dostępny w Railsach 5, ale nie może być zaimplementowany w ten sposób, ponieważ oczekuje przekazania 1 argumentu. Oczekuje obiektu Arel. Zobacz zaakceptowaną odpowiedźor
Metoda ActiveRecord działa, jeśli używasz go bezpośrednio, lecz może złamać swoje oczekiwania, jeśli jest stosowany w zakresie, który jest następnie przykuty.Railsy niedawno dodały to do ActiveRecord. Wygląda na to, że został wydany w Railsach 5. Zaangażowany w opanowanie:
https://github.com/rails/rails/commit/9e42cf019f2417473e7dcbfcb885709fa2709f89
Post.where(column: 'something').or(Post.where(other: 'else')) # => SELECT * FROM posts WHERE (column = 'something') OR (other = 'else)
źródło
Rails 5 zawiera
or
metodę. (l atrament do dokumentacji )Ta metoda akceptuje
ActiveRecord::Relation
obiekt. na przykład:User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
źródło
Jeśli chcesz używać tablic jako argumentów, następujący kod działa w Railsach 4:
query = Order.where(uuid: uuids, id: ids) Order.where(query.where_values.map(&:to_sql).join(" OR ")) #=> Order Load (0.7ms) SELECT "orders".* FROM "orders" WHERE ("orders"."uuid" IN ('5459eed8350e1b472bfee48375034103', '21313213jkads', '43ujrefdk2384us') OR "orders"."id" IN (2, 3, 4))
Więcej informacji: LUB zapytania z tablicami jako argumentami w Railsach 4 .
źródło
Order.where(query.where_values.inject(:or))
używać arel do końca.MetaWhere Wtyczka jest zupełnie niesamowite.
Łatwo mieszaj OR i AND, dołącz warunki w dowolnej asocjacji, a nawet określ OUTER JOIN!
Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}
źródło
Po prostu dodaj OR w warunkach
Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
źródło
Możesz to zrobić tak:
Person.where("name = ? OR age = ?", 'Pearl', 24)
lub bardziej eleganckie, zainstaluj rails_or gem i zrób to tak:
Person.where(:name => 'Pearl').or(:age => 24)
źródło
Właśnie wyodrębniłem tę wtyczkę z pracy klienta, która pozwala łączyć zakresy z
.or.
, np.Post.published.or.authored_by(current_user)
. Squeel (nowsza implementacja MetaSearch) jest również świetny, ale nie pozwala na zakresy LUB, więc logika zapytań może stać się nieco zbędna.źródło
Z railami + arel, bardziej przejrzysty sposób:
# Table name: messages # # sender_id: integer # recipient_id: integer # content: text class Message < ActiveRecord::Base scope :by_participant, ->(user_id) do left = arel_table[:sender_id].eq(user_id) right = arel_table[:recipient_id].eq(user_id) where(Arel::Nodes::Or.new(left, right)) end end
Produkuje:
$ Message.by_participant(User.first.id).to_sql => SELECT `messages`.* FROM `messages` WHERE `messages`.`sender_id` = 1 OR `messages`.`recipient_id` = 1
źródło
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')
źródło
Chciałbym dodać, że jest to rozwiązanie do wyszukiwania wielu atrybutów ActiveRecord. Od
.where(A: param[:A], B: param[:B])
wyszuka A i B.
źródło