web-dev-qa-db-fra.com

Ruby on Rails 3 comment faire la condition 'OU')

J'ai besoin d'une instruction SQL qui vérifie si une condition est remplie:

SELECT * FROM my_table WHERE my_table.x=1 OR my_table.y=1

Je veux le faire de la manière "Rails 3". Je cherchais quelque chose comme:

Account.where(:id => 1).or.where(:id => 2)

Je sais que je peux toujours recourir à SQL ou à une chaîne de conditions. Cependant, d'après mon expérience, cela conduit souvent au chaos lors de la combinaison des portées. Quelle est la meilleure façon de procéder?

Une autre question connexe est de savoir comment décrire une relation qui dépend d'une condition OR. La seule façon que j'ai trouvée:

has_many :my_thing, :class_name => "MyTable",  :Finder_sql => 'SELECT my_tables.* ' + 'FROM my_tables ' +
'WHERE my_tables.payer_id = #{id} OR my_tables.payee_id = #{id}'

Cependant, ceux-ci se cassent à nouveau lorsqu'ils sont utilisés en combinaison. IS existe-t-il une meilleure façon de spécifier cela?

50
hjuskewycz

Malheureusement, le .or n'est pas encore implémenté (mais quand il le sera, ce sera IMPRESSIONNANT).

Vous devrez donc faire quelque chose comme:

class Project < ActiveRecord::Base
  scope :sufficient_data, :conditions=>['ratio_story_completion != 0 OR ratio_differential != 0']
  scope :profitable, :conditions=>['profit > 0']

De cette façon, vous pouvez toujours être génial et faire:

Project.sufficient_data.profitable
9
Jesse Wolgamott

Account.where(id: [1,2]) aucune explication nécessaire.

114
Mike Campbell

Cela fonctionnera dans Rails 5, voir Rails master :

Post.where('id = 1').or(Post.where('id = 2'))
# => SELECT * FROM posts WHERE (id = 1) OR (id = 2)

Pour Rails 3.0.4+:

accounts = Account.arel_table
Account.where(accounts[:id].eq(1).or(accounts[:id].eq(2)))
72
weston

Ces requêtes arel sont illisibles pour moi.

Quel est le problème avec une chaîne SQL? En fait, le guide Rails expose cette façon comme la première façon de créer des conditions dans les requêtes: http://guides.rubyonrails.org/active_record_querying.html#array-conditions

Donc, je parie pour cette façon de faire comme la "voie Rails":

Account.where("id = 1 OR id = 2")

À mon humble avis, c'est plus court et plus clair.

16
David Morales

J'irais avec la clause IN, par exemple:

Account.where(["id in (?)", [1, 2]])
6
jpemberthy

J'ai utilisé la gemme Squeel ( https://github.com/ernie/squeel/ ) pour faire OR requêtes et cela fonctionne à merveille.

Il vous permet d'écrire votre requête sous la forme Account.where{(id == 1) | (id == 2)}

5
brad

Vous pouvez définir un tableau comme valeur dans le :conditions Hash.

Vous pouvez donc faire par exemple:

Account.all(:conditions => { :id => [1, 2] })

Testé avec Rails 3.1.0

4
TehQuila

Syntaxe alternative utilisant Hash

Account.where("id = :val1 OR id = :val2", val1: 1, val2: 2).

Ceci est particulièrement utile lorsque la valeur est comparée à plusieurs colonnes. par exemple:

User.where("first_name = :name OR last_name = :name", name: 'tom')
2
Santhosh

Avec Rails_or , vous pourriez le faire comme:

Account.where(id: 1).or(id: 2)

(Cela fonctionne en Rails 4 et 5, aussi.)

0
khiav reoy