Comment faire une requête OR dans Rails 3 ActiveRecord. Tous les exemples que je trouve ont juste ET des requêtes.
Edit: La méthode _ ou _ est disponible depuis Rails 5. Voir ActiveRecord :: QueryMethods
Utilisez ARel
t = Post.arel_table
results = Post.where(
t[:author].eq("Someone").
or(t[:title].matches("%something%"))
)
Le SQL résultant:
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%'))
Si vous souhaitez utiliser un opérateur OR sur la valeur d'une colonne, vous pouvez transmettre un tableau à .where
et ActiveRecord utilisera IN(value,other_value)
:
Model.where(:column => ["value", "other_value"]
les sorties:
SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value')
Cela devrait atteindre l'équivalent d'un OR
sur une seule colonne
dans Rails 3, il devrait être
Model.where("column = ? or other_column = ?", value, other_value)
Cela inclut également le sql brut, mais je ne pense pas qu’il existe un moyen dans ActiveRecord de procéder à une opération OR. Votre question n'est pas une question de noob.
Une version mise à jour de Rails/ActiveRecord peut prendre en charge cette syntaxe de manière native. Cela ressemblerait à:
Foo.where(foo: 'bar').or.where(bar: 'bar')
Comme indiqué dans cette demande d'extraction https://github.com/Rails/rails/pull/9052
Pour l'instant, il suffit de s'en tenir aux travaux suivants:
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
Mise à jour: Selon https://github.com/Rails/rails/pull/16052 la or
fonctionnalité sera disponible dans Rails 5
Mise à jour: La fonction a été fusionnée dans la branche Rails 5.
Rails a récemment ajouté cela à ActiveRecord. Il semble être publié dans Rails 5. Engagé à maîtriser déjà:
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)
Rails 5 est livré avec une méthode or
. (l encre à la documentation )
Cette méthode accepte un objet ActiveRecord::Relation
. par exemple:
User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
Si vous souhaitez utiliser des tableaux comme arguments, le code suivant fonctionne dans 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))
Plus d'informations: OU requêtes avec des tableaux comme arguments dans Rails 4 .
Le plugin MetaWhere est complètement incroyable.
Vous pouvez facilement mélanger les OR et les AND, associer des conditions à toute association et même spécifier des OUTER JOIN!
Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}
Ajoutez simplement un OR dans les conditions
Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
Je viens d'extraire ce plugin du travail client qui vous permet de combiner des étendues avec .or.
, ex. Post.published.or.authored_by(current_user)
. Squeel (la nouvelle implémentation de MetaSearch) est également génial, mais ne vous permet pas d'étendre la portée OR, de sorte que la logique de requête peut devenir un peu redondante.
Vous pourriez le faire comme:
Person.where("name = ? OR age = ?", 'Pearl', 24)
ou plus élégant, installez Rails_or gem et procédez comme suit:
Person.where(:name => 'Pearl').or(:age => 24)
Avec Rails + arel, une manière plus claire:
# 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
Produit:
$ Message.by_participant(User.first.id).to_sql
=> SELECT `messages`.*
FROM `messages`
WHERE `messages`.`sender_id` = 1
OR `messages`.`recipient_id` = 1