【发布时间】:2011-09-13 09:24:39
【问题描述】:
我使用下面的method_missing实现给某个模型一个适应性强的named_scope过滤:
class Product < ActiveRecord::Base
def self.method_missing(method_id, *args)
# only respond to methods that begin with 'by_'
if method_id.to_s =~ /^(by\_){1}\w*/i
# extract column name from called method
column = method_id.to_s.split('by_').last
# if a valid column, create a dynamic named_scope
# for it. So basically, I can now run
# >>> Product.by_name('jellybeans')
# >>> Product.by_vendor('Cyberdine')
if self.respond_to?( column.to_sym )
self.send(:named_scope, method_id, lambda {|val|
if val.present?
# (this is simplified, I know about ActiveRecord::Base#find_by_..)
{ :conditions => ["#{base.table_name}.#{column} = ?", val]}
else
{}
end
})
else
super(method_id, args)
end
end
end
end
我知道 ActiveRecord::Base 已经使用find_by_<X> 提供了这一点,但我试图超越我给出的示例,并为我的应用程序提供一些定制的过滤。我想让它可供选定的模型使用,而不必在每个模型类中粘贴这个 sn-p。我想过使用一个模块,然后将它混合到选择的模型中——我只是对语法有点含糊。
当错误开始堆积时,我已经做到了这一点(我这样做对吗?):
module GenericFilter
def self.extended(base)
base.send(:method_missing, method_id, *args, lambda { |method_id, args|
# ?..
})
end
end
那我希望可以这样使用:
def Product < ActiveRecord::Base
include GenericFilter
end
def Vendor < ActiveRecord::Base
include GenericFilter
end
# etc..
任何帮助都会很棒 - 谢谢。
【问题讨论】:
标签: ruby-on-rails activerecord refactoring named-scope mixins