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?
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
Account.where(id: [1,2])
aucune explication nécessaire.
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)))
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.
J'irais avec la clause IN
, par exemple:
Account.where(["id in (?)", [1, 2]])
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)}
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
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')
Avec Rails_or , vous pourriez le faire comme:
Account.where(id: 1).or(id: 2)
(Cela fonctionne en Rails 4 et 5, aussi.)