web-dev-qa-db-fra.com

ActiveRecord OR interrogation en notation hachée

Je sais qu'il existe 3 notations principales pour fournir des arguments à la méthode where ActiveRecord:

  1. Pure String
  2. Tableau
  3. Hacher

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

# Pure String 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})

Spécifier or pour cette même méthode where m'agace pour la syntaxe de hachage. C'est possible?

# Pure String 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})
72
Neil

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 hash - ish ):

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

    Person.where(name: 'Neil').or(Person.where(age: 27))
    
  2. Utilisation where_values avec reduce . La méthode unscoped est nécessaire niquement pour Rails 4.1 + pour assurer default_scope n'est pas inclus dans le where_values. Sinon, les prédicats des deux default_scope et where seraient chaînés avec l’opérateur or:

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

    • Où O (port du Ruby sur 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 paramètres nommés:

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

Comme dit potashin, vous pouvez utiliser d'autres plugins tiers qui implémentent cette fonctionnalité. J'ai longtemps utilisé Squeel et fonctionne assez bien pour cela, et beaucoup plus de fonctionnalités telles que des sous-requêtes complexes ou des jointures.

Cette requête utilisant squeel:

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