ActiveRecord OU requête Notation de hachage

Je sais qu’il y a 3 notations principales pour fournir des arguments à la méthode where ActiveRecord:

  1. Pur fil
  2. Tableau
  3. Hacher

Spécifier and pour la méthode where méthode est simple:

 # Pure Ssortingng notation Person.where("name = 'Neil' AND age = 27") # Array notation Person.where(["name = ? AND age = ?", 'Neil', 27]) # Hash notation Person.where({name: "Neil", age: 27}) 

En spécifiant or pour cette même méthode, la méthode me pose problème pour la syntaxe de hachage. C’est possible?

 # Pure Ssortingng notation Person.where("name = 'Neil' OR age = 27") # Array notation Person.where(["name = ? OR age = ?", 'Neil', 27]) # Hash notation DOESN'T WORK Person.where({name: "Neil" OR age: 27}) 

Il y a 5 options qui pourraient être considérées comme des implémentations de «notation de hachage» (les deux dernières sont un peu de hash):

  1. Avec Ruby on Rails 5, vous pouvez faire le chaînage suivant avec ActiveRecord::Relation#or méthode:

     Person.where(name: 'Neil').or(Person.where(age: 27)) 
  2. Utilisez les where_values avec where_values . La méthode non unscoped est nécessaire uniquement pour Rails 4.1+ pour s’assurer que default_scope n’est pas inclus dans where_values . Sinon, les prédicats de default_scope et where seraient enchaînés avec l’opérateur or :

     Person.where( Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) ) 
  3. Installez des plug-ins tiers qui implémentent ces fonctionnalités ou des fonctionnalités similaires, par exemple:

    • Où Ou (backport du Ruby on Rails 5 .or fonctionnalité mentionnée ci-dessus)

    • Squeel

       Person.where{(name == 'Neil') | (age == 27)} 
    • RailsOr

       Person.where(name: 'Neil').or(age: 27) 
    • ActiverecordAnyOf

       Person.where.anyof(name: 'Neil', age: 27) 
    • SmartTuple

       Person.where( (SmartTuple.new(' or ') << {name: 'Neil', age: 27}).compile ) 
  4. Utilisez Arel :

     Person.where( Person.arel_table[:name].eq('Neil').or( Person.arel_table[:age].eq(27) ) ) 
  5. Utilisez des instructions préparées avec des parameters nommés:

     Person.where('name = :name or age = :age', name: 'Neil', age: 27) 

Comme dit potashin, vous pouvez utiliser un autre plug-in tiers qui implémente cette fonctionnalité. J’utilise Squeel depuis longtemps et fonctionne plutôt bien pour cela et bien d’autres fonctionnalités comme les sous-requêtes complexes ou les jointures.

Cette requête en utilisant squeel:

 @people= Person.where{(name == 'Neil') | (age = 27)}