web-dev-qa-db-fra.com

Comment utiliser OR condition dans la requête ActiveRecord

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.

21
Matt Elhotiby

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]'))
35
Santhosh

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)
12
Anil

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')
)
8
tokland

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')}
5
DGM

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.

Cf Guide d'interface Active Record Query

0
ksol