我正在尝试向事件记录对象动态添加范围。我做过的一些事trying通过元编程不起作用。以下是我想要实现的目标。
class UtilityClass
def add_scope_to_class klass, name, lambda
# should add something like
# scope :published, -> { where(published: true) }
code = lambda { filter_clause(value, &lambda) }
klass.class_exec(&code)
end
end
class Article < ActiveRecord::Base
end
UtilityClass.add_scope_to_class
Article.published # returns published articles
我已经用普通的 ruby 对象尝试了几个变体,但我认为用这个上下文问这个问题可能会得到一些不同的想法/答案。
谢谢。
已更新
到目前为止,我已经设法想出以下方法,但它不起作用
class ActiveSearch
attr_accessor :collection
attr_reader :params
def initialize params={}
@params = params
end
def results
@collection = Person.where(nil)
params.compact.each do |key, value|
@collection = @collection.send("#{key}_filter", value)
end
@collection
end
def self.filter name, filter_proc
code = lambda { |filter_name| scope("#{filter_name.to_s}_filter".to_s, filter_proc) }
Person.class_exec(name, &code)
end
end
class PersonSearch < ActiveSearch
filter :first_name, ->(name){ where(first_name: name) }
end
我硬编码了几件事。主要思想就在那里。
最佳答案
经过反复尝试,我发现解决方案比我最初想象的要简单一些。
class ActiveSearch
attr_accessor :collection
attr_reader :params
def initialize params={}
@params = params
end
def results
@collection = Person.where(nil)
params.compact.each do |key, value|
@collection = @collection.send("#{key}_filter", value)
end
@collection
end
def self.filter name, filter_proc
Person.define_singleton_method "#{name.to_s}_filter".to_sym, &filter_proc # does most of the heavy lifting
end
end
class PersonSearch < ActiveSearch
filter :first_name, lambda { |name| where(first_name: name) }
filter :last_name, lambda { |name| where(last_name: name) }
end
PersonSearch.new({first_name: 'ryan', last_name: 'test'}).results
以上将组合所有适当的方法并执行查询。
需要进行一些调整,但它几乎可以满足我的要求。事件搜索类仍然需要清理并使其通用化,但我认为它传达了这个想法。
关于ruby - 有没有办法动态地将范围添加到事件记录类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30823394/