Comment faire une requête OR dans Rails 3 ActiveRecord. Tous les exemples que je trouve ont juste des requêtes AND.
Edit: la méthode OR est disponible depuis Rails 5. Voir ActiveRecord :: QueryMethods
ruby-on-rails
ruby-on-rails-3
rails-activerecord
pho3nixf1re
la source
la source
Post.where(column: 'something').or(Post.where(other: 'else'))
Réponses:
Utiliser 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%'))
la source
matches
produiraLIKE
pour sqlite (insensible à la casse par défaut) etILIKE
sur postgres (nécessite explicitement insensible à la casse comme opérateur).Si vous souhaitez utiliser un opérateur OR sur la valeur d'une colonne, vous pouvez passer un tableau à
.where
et ActiveRecord utiliseraIN(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 colonnela source
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 faire une opération OR. Votre question n'est pas une question noob.
la source
Page.where("pages.column = ? or pages.other_column = ?", value, other_value)
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 éléments 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 5Mise à jour: la fonctionnalité a été fusionnée avec la branche Rails 5
la source
or
est disponible maintenant Rails 5 mais pas implémenté de cette façon car il s'attend à ce qu'un argument soit passé. Il attend un objet Arel. Voir la réponse acceptéeor
méthode dans ActiveRecord fonctionne si vous l'utilisez directement: mais peut briser vos attentes si elle est utilisée dans une portée qui est ensuite chaînée.Rails l'a récemment ajouté dans ActiveRecord. Il semble être publié dans Rails 5. Déjà engagé à maîtriser:
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)
la source
Rails 5 est livré avec une
or
méthode. (l encre à la documentation )Cette méthode accepte un
ActiveRecord::Relation
objet. par exemple:User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
la source
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: Requêtes OR avec des tableaux comme arguments dans Rails 4 .
la source
Order.where(query.where_values.inject(:or))
utiliser arel jusqu'au bout.Le plugin MetaWhere est complètement incroyable.
Mélangez facilement les OU et les AND, joignez les conditions sur n'importe quelle association et spécifiez même OUTER JOIN!
Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}
la source
Ajoutez simplement un OU dans les conditions
Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
la source
Vous pouvez le faire comme:
Person.where("name = ? OR age = ?", 'Pearl', 24)
ou plus élégant, installez rails_or gem et faites-le comme:
Person.where(:name => 'Pearl').or(:age => 24)
la source
Je viens d'extraire ce plugin du travail client qui vous permet de combiner des portées avec
.or.
, ex.Post.published.or.authored_by(current_user)
. Squeel (implémentation plus récente de MetaSearch) est également géniale, mais ne vous permet pas d'étendues OU, donc la logique de requête peut devenir un peu redondante.la source
Avec rails + arel, une voie 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
la source
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')
la source
Je voudrais ajouter que c'est une solution pour rechercher plusieurs attributs d'un ActiveRecord. Depuis
.where(A: param[:A], B: param[:B])
recherchera A et B.
la source