Je veux saisir tous les utilisateurs qui ont soit un email que celui fourni ou le prénom et le nom. Donc par exemple:
users = User.where(:first_name => "James", :last_name => "Scott")
qui retournera tous les utilisateurs qui ont le prénom et le nom de "James" & "Scott".
users = User.where(:email => "[email protected]")
qui renverra l'utilisateur avec le courrier électronique sous la forme "[email protected]".
Existe-t-il un moyen de créer une clause where
pour renvoyer les utilisateurs avec les mêmes prénom et nom et l'utilisateur avec le courrier électronique correspondant à une requête where
ou dois-je effectuer une fusion sur les 2 clauses where
distinctes.
Rails 5 est livré avec une méthode or
.
Cette méthode accepte un objet ActiveRecord::Relation
. par exemple:
User.where(first_name: 'James', last_name: 'Scott')
.or(User.where(email: '[email protected]'))
Essaye ça:
users = User.where("(first_name = 'James' and last_name = 'Scott') or email = '[email protected]'")
Pour interpoler des variables:
users = User.where("(first_name = ? and last_name = ?) or email = ?", first_name, last_name, email)
Si vous préférez une approche DSL (sans SQL), vous pouvez utiliser la couche Arel sous-jacente:
t = User.arel_table
users = User.where(
(t[:first_name].eq('Ernie').and(t[:last_name].eq('Scott')).
or(t[:email].eq('james#gmail.com'))
)
C'est un peu moche, mais si vous utilisez un wrapper sur Arel (par exemple, celui-ci ), le code est beaucoup plus agréable:
users = User.where(
((User[:first_name] == 'Ernie') & (User[:last_name] == 'Scott')) |
(User[:email] == 'james#gmail.com')
)
Si vous ne voulez pas écrire SQL comme les autres l’ont mentionné, vous pouvez accéder directement aux structures arel (on dirait qu’une autre réponse a cette réponse) ou utiliser le squeel gem pour le faire beaucoup plus élégamment:
User.where{(first_name == 'Ernie') & (last_name == 'Scott') | (email == 'james#gmail.com')}
Vous pouvez utiliser des conditions de chaîne, comme dans Client.where("orders_count = ? AND locked = ?", params[:orders], false)
, et utiliser OR
conjointement avec AND
. Soyez prudent avec la priorité de ces opérateurs cependant.