2010-08-23 18 views
10

ho bisogno di coniugare nome di ambito con o operatore ... Qualcosa di simile:Rails3: combinare portata con OR

class Product < ActiveRecord::Base 
    belongs_to :client 

    scope :name_a, where("products.name = 'a'") 
    scope :client_b, joins(:client).where("clients.name = 'b'") 

    scope :name_a_or_b, name_a.or(client_b) 
end 

Thx

risposta

9

Da Arel documentation

L'operatore non è OR ancora supportato. Si lavorerà in questo modo: users.where(users[:name].eq('bob').or(users[:age].lt(25)))

This RailsCast vi mostra come utilizzare l'operatore .or. Tuttavia, funziona con gli oggetti Arel mentre si hanno istanze di ActiveRecord::Relation. Puoi convertire una relazione in Arel usando Product.name_a.arel, ma ora devi capire come unire le condizioni.

8

Heres un hack che userei per affrontare questa caratteristica mancante:

class Product < ActiveRecord::Base 
    belongs_to :client 

    class << self 
    def name_a 
     where("products.name = 'a'") 
    end 

    def client_b 
     joins(:client).where("clients.name = 'b'") 
    end 

    def name_a_or_b 
     clauses = [name_a, client_b].map do |relation| 
     clause = relation.arel.where_clauses.map { |clause| "(#{clause})" }.join(' AND ') 
     "(#{clause})" 
     end.join(' OR ') 

     where clauses 
    end 
    end 
end 
+0

Genius! Grazie –

3

Per Rails 3:

Person.where(
    Person.where(name: "John").where(lastname: "Smith").where_values.join(' OR ') 
)