64

So che ci sono 3 notazioni principali per fornire argomenti al metodo where ActiveRecord:ActiveRecord O interrogazione Hash notazione

  1. pura stringa
  2. Array
  3. Hash

Specifica and per la Il metodo where è diretto:

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

Specificare or per questo stesso metodo where mi sta bloccando per la sintassi dell'hash. È possibile?

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

risposta

126

Ci sono 5 opzioni che potrebbero essere considerati come implementazioni di «Hash notazione» (gli ultimi due sono un pò di hashing ish):

  1. con Ruby on Rails 5 si sono in grado per effettuare le seguenti catena tramite ActiveRecord::Relation#or metodo:

    Person.where(name: 'Neil').or(Person.where(age: 27)) 
    
  2. Uso where_values insieme 0.123.615,637 mila. Il metodo unscoped è necessario only for Rails 4.1+ per garantire che default_scope non sia incluso nello where_values.predicati altrimenti sia default_scope e where sarebbe concatenato con il or esercente:

    Person.where( 
        Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) 
    ) 
    
  3. installare plugin di terze parti che implementano queste o simili caratteristiche, ad esempio:

    • Where Or(backport la funzione Ruby on Rails 5 .or menzionata sopra)

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

    Person.where( 
        Person.arel_table[:name].eq('Neil').or(
        Person.arel_table[:age].eq(27) 
    ) 
    ) 
    
  5. Usa istruzioni preparate con parametri denominati:

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

Questa è una risposta completa. La risposta di 'arel' è particolarmente buona poiché questo è ciò che viene aggiunto a Rails 5, come ho capito. –

+0

Se non si riesce ad attendere Rails 5, è possibile utilizzare questo backport della funzione alle guide 4.2. Ben confezionato come il 'dove-o' gemma https://github.com/Eric-Guo/where-or – Rob

+0

Se il tuo progetto è ancora in Rails 3+, puoi provare i rails_or gem: https: // github. com/khiav223577/rails_or –

1

Come dice potashin, è possibile utilizzare un altro plugin di terze parti che implementano questa funzione . Ho molto tempo usando Squeel e funziona abbastanza bene per questo e molte altre funzionalità come subquery o join complessi.

Che query utilizzando squeel:

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