ActiveRecord ODER Abfrage

Wie führen Sie eine OR-Abfrage in Rails 3 ActiveRecord durch? Alle Beispiele, die ich finde, haben UND-Anfragen.

Bearbeiten: OR- Methode ist seit Rails verfügbar 5. Siehe ActiveRecord :: QueryMethods

Solutions Collecting From Web of "ActiveRecord ODER Abfrage"

Benutze ARel

 t = Post.arel_table results = Post.where( t[:author].eq("Someone"). or(t[:title].matches("%something%")) ) 

Das resultierende 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%')) 

Wenn Sie einen OR-Operator für den Wert einer Spalte verwenden möchten, können Sie ein Array an .where und .where verwendet IN(value,other_value) :

Model.where(:column => ["value", "other_value"]

Ausgänge:

 SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value') 

Dies sollte das Äquivalent eines OR für eine einzelne Spalte erreichen

in Rails 3 sollte es sein

 Model.where("column = ? or other_column = ?", value, other_value) 

Dazu gehört auch root sql, aber ich denke nicht, dass ActiveRecord eine Möglichkeit bietet, die Operation OR durchzuführen. Ihre Frage ist keine Frage.

Eine aktualisierte Version von Rails / ActiveRecord kann diese Syntax nativ unterstützen. Es würde ähnlich aussehen:

 Foo.where(foo: 'bar').or.where(bar: 'bar') 

Wie in dieser Pull-Anforderung angegeben https://github.com/rails/rails/pull/9052

Fürs Erste ist es einfach großartig, sich an folgende Arbeiten zu halten:

 Foo.where('foo= ? OR bar= ?', 'bar', 'bar') 

Update: Nach https://github.com/rails/rails/pull/16052 wird das Feature in Rails 5 verfügbar sein

Update: Feature wurde in Rails 5-Zweig zusammengeführt

Rails hat dies kürzlich zu ActiveRecord hinzugefügt. Es scheint in Rails 5 veröffentlicht zu werden. Committed, um bereits zu meistern:

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) 

Wenn Sie Arrays als Argumente verwenden möchten, funktioniert der folgende Code in Rails 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)) 

Weitere Informationen: OR-Abfragen mit Arrays als Argumente in Rails 4 .

Rails 5 kommt mit einer or Methode. (l Tinte zur Dokumentation )

Diese Methode akzeptiert ein ActiveRecord::Relation Objekt. z.B:

 User.where(first_name: 'James').or(User.where(last_name: 'Scott')) 

Das MetaWhere Plugin ist absolut fantastisch.

Mischen Sie einfach ORs und ANDs, verbinden Sie Bedingungen für jede Assoziation und spezifizieren Sie sogar OUTER JOINs!

 Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer} 

Fügen Sie einfach ein OR in den Bedingungen hinzu

 Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value]) 

Ich habe dieses Plugin nur aus der Client-Arbeit extrahiert, mit der Sie Bereiche mit .or. kombinieren .or. , Ex. Post.published.or.authored_by(current_user) . Squeel (neuere Implementierung von MetaSearch) ist auch großartig, aber Sie können nicht ODER Bereiche, so Abfrage Logik kann ein bisschen überflüssig.

Du könntest es tun wie:

 Person.where("name = ? OR age = ?", 'Pearl', 24) 

oder eleganter, installiere rails_or gem und mach es so:

 Person.where(:name => 'Pearl').or(:age => 24) 

Mit Rails + Arel, ein klarer Weg:

 # 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 

Produziert:

 $ Message.by_participant(User.first.id).to_sql => SELECT `messages`.* FROM `messages` WHERE `messages`.`sender_id` = 1 OR `messages`.`recipient_id` = 1 
 Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')