risposta

153

La capacità di catena or clausola insieme where clausola ActiveRecord interrogazione sarà disponibile in Rotaie 5. Vedi lo related discussion and the pull request.

Quindi, si sarà 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) 
+3

Come posso ottenere (A || B) && (C || D). Ho provato Post.where (a) .or (Post.where (b)). Where (c) .or (Post.where (d)) ma produce come: (A || B) && C || D – Imran

+3

@Imran credo che sarebbe 'Post.where (a) .or (Post.where (b)). Dove (Post.where (c) .or (Post.where (d)))' questo dovrebbe creare (a || b) && (c || d) – engineersmnky

12

Non abbiamo bisogno di aspettare per le rotaie 5 per utilizzare questo OR query. Possiamo anche usarlo con rails 4.2.3. C'è un backport here.

Grazie a Eric-Guo per gemma where-or, Ora possiamo aggiungere questa funzionalità OR in >= rails 4.2.3 utilizzando anche questo gioiello.

3

avevo bisogno di fare un (A && B) || (C && D) || (E && F)

Ma allo stato attuale l' Rails 5.1.4 questo ottenere di troppo complicato da realizzare con l'Arel o catena. Ma volevo ancora usare Rails per generare quanta più query possibile.

Così ho fatto un piccolo trucco:

Nel mio modello ho creato un metodo privatochiamato sql_where:

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

successiva nel mio ambito ho creato un array per contenere del 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 ')) 
} 

Che 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.

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

Problemi correlati