ActiveRecord O consulta hash Hash

Sé que hay 3 notaciones principales para el suministro de argumentos al método where ActiveRecord:

  1. Cadena pura
  2. Formación
  3. Picadillo

Especificar and para el método where es sencillo:

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

Especificar or para este mismo método where me está incomodando por la syntax hash. ¿Es posible?

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

Hay 5 opciones que podrían considerarse como implementaciones de la “notación hash” (las dos últimas son algo hashish):

  1. Con Ruby on Rails 5 puede hacer el siguiente encadenamiento utilizando ActiveRecord::Relation#or método:

     Person.where(name: 'Neil').or(Person.where(age: 27)) 
  2. Usa where_values junto con reduce . El método sin unscoped solo es necesario para Rails 4.1+ para garantizar que default_scope no se incluya en los where_values . De lo contrario, predica de default_scope y de where estaría encadenado con el operador or :

     Person.where( Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) ) 
  3. Instale complementos de terceros que implementen estas características o similares, por ejemplo:

    • Where O (soporte de Ruby on Rails 5. .or característica mencionada anteriormente)

    • 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. Use Arel :

     Person.where( Person.arel_table[:name].eq('Neil').or( Person.arel_table[:age].eq(27) ) ) 
  5. Use declaraciones preparadas con parámetros nombrados:

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

Como dice potashin, puede usar otros complementos de terceros que implementen esta función. Tengo mucho tiempo para usar Squeel y funciona bastante bien para esto y muchas más características, como subconsultas complejas o combinaciones.

Esa consulta usando squeel:

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