Skip to content

Instantly share code, notes, and snippets.

@JuarezLustosa
Created June 26, 2012 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JuarezLustosa/2995355 to your computer and use it in GitHub Desktop.
Save JuarezLustosa/2995355 to your computer and use it in GitHub Desktop.
class Payment < ActiveRecord::Base
def self.filtered(restrictions)
PaymentFilter.new(self.scoped).restrict(restrictions)
end
def self.year(year)
where(:year => year)
end
def self.person_id(person_id)
where(:person_id => person_id)
end
def self.taxable(taxable_type, taxable_id)
where(:taxable_type => taxable_type, :taxable_id => taxable_id)
end
end
class PaymentFilter
def initialize(relation)
self.relation = relation
end
def restrict(restrictions)
year! restrictions[:year] if restrictions[:year]
person_id! restrictions[:person_id] if restrictions[:person_id]
taxable! restrictions[:taxable_type], restrictions[:taxable_id] if restrictions[:taxable_type] && restrictions[:taxable_id]
relation
end
protected
attr_accessor :relation
def year!(year)
self.relation = relation.year(year)
end
def person_id!(person_id)
self.relation = relation.person_id(person_id)
end
def taxable!(taxable_type, taxable_id)
self.relation = relation.taxable(taxable_type, taxable_id)
end
end
restrictions = { :year => '1998', :person_id => 37, :taxable_type => 'Property', :taxable_id => 42 }
payments = Payment.filtered(restrictions)
payments.each do |payment|
puts payment.year
puts payment.person
puts payment.taxable
end
@otaviocardoso
Copy link

No exemplo do site, o filtro tem uma espécie de delegate do where para a relation. Poderia fazer isso para fazer o where direto no filtro e eliminar os métodos do modelo =D

@otaviocardoso
Copy link

No site, o autor incluiu esse método na classe do filter:

def where(*a)
  @relation = @relation.where(*a)
end

Eu acho que seria mais simples só colocar um delegate pro relation assim:

# attr_reader :relation # já tem o attr_accessor no exemplo
delegate :where, :to => :relation

De qualquer forma, a ideia é a mesma do autor do post, chamar o where no próprio filter.

UPDATE

Faltou como o código de um dos filters ficaria:

def year!(year)
  self.relation = where(:year => year)
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment