Rails 5: ActiveRecord O query

Come si fa or si esegue una query in Rails 5 ActiveRecord? Inoltre, è ansible concatenare or con where query ActiveRecord?

La capacità di concatenare or clausola insieme alla clausola where nella query ActiveRecord sarà disponibile in Rails 5 . Vedi la discussione relativa e la richiesta di pull .

Quindi, sarai in grado di fare le seguenti cose in Rails 5 :

Per ottenere un post con id 1 o 2:

 Post.where('id = 1').or(Post.where('id = 2')) 

Alcuni altri esempi:

(A && B) || C:

  Post.where(a).where(b).or(Post.where(c)) 

(A || B) && C:

  Post.where(a).or(Post.where(b)).where(c) 

Non è necessario attendere che i binari 5 utilizzino questa query OR . Possiamo anche usarlo con le rails 4.2.3 . C’è un backport qui .

Grazie a Eric-Guo per la gem dove-o , Ora possiamo aggiungere questa funzionalità OR in >= rails 4.2.3 usando anche questa gem.

Dovevo fare un (A && B) || (C && D) || (E && F) (A && B) || (C && D) || (E && F)

Ma nello stato attuale di Rails 5.1.4 questo get è troppo complicato da realizzare con la catena di Arel. Ma volevo comunque utilizzare Rails per generare il maggior numero ansible di query.

Così ho fatto un piccolo trucco:

Nel mio modello ho creato un metodo privato chiamato sql_where :

 private def self.sql_where(*args) sql = self.unscoped.where(*args).to_sql match = sql.match(/WHERE\s(.*)$/) "(#{match[1]})" end 

Successivamente nel mio ambito ho creato un array per contenere gli OR

 scope :whatever, -> { ors = [] ors << sql_where(A, B) ors << sql_where(C, D) ors << sql_where(E, F) # Now just combine the stumps: where(ors.join(' OR ')) } 

Quale produrrà il risultato della query prevista: SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F)) .

E ora posso facilmente combinare questo con altri ambiti ecc. Senza alcun OR errato.

Il bello è che il mio sql_where usa normali argomenti where-clause: sql_where(name: 'John', role: 'admin') genererà (name = 'John' AND role = 'admin') .

(Solo un’aggiunta alla risposta di KM Rakibul Islam.)

Usando gli ambiti, il codice può diventare più carino (a seconda degli occhi):

 scope a, -> { where(a) } scope b, -> { where(b) } scope a_or_b, -> { a.or(b) }