我正在创建一个插件,并且很难定义一个调用我刚刚定义的实例方法的before_save过滤器。这是一个快速的样本:
module ValidatesAndFormatsPhones
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def validates_and_formats_phones(field_names = [:phone])
send :include, InstanceMethods
# the following variations on calls to :format_phone_fields fail
before_save send(:format_phone_fields, field_names)
before_save format_phone_fields(field_names)
before_save lambda { send(:format_phone_fields, field_names) }
# EACH OF THE ABOVE RETURNS 'undefined_method :format_phone_fields'
end
end
module InstanceMethods
def format_phone_fields(fields = [:phone], *args)
do stuff...
end
end
end
ActiveRecord::Base.send :include, ValidatesAndFormatsPhones
我想问题是,如何更改实例的上下文而不是类?
我更喜欢调用实例方法,因为类不应该有一个名为'format_phone_fields'的方法,但实例应该。
谢谢!
答案 0 :(得分:4)
在适当的时候包括您的方法:当您扩展基类时:
module ValidatesAndFormatsPhones
def self.included(base)
base.send :extend, ClassMethods
base.send :include, InstanceMethods
end
module ClassMethods
def validates_and_formats_phones(field_names = [:phone])
before_save {|r| r.format_phone_fields(field_names)}
end
end
module InstanceMethods
def format_phone_fields(fields = [:phone], *args)
# do stuff...
end
end
end
ActiveRecord::Base.send :include, ValidatesAndFormatsPhones
我没有运行代码,但应该可以运行。我经常做类似的事情。
答案 1 :(得分:2)
当您使用回调宏时,您只能传递要运行的方法的符号,无法传递参数。 rails文档中的'workaround'是使用在正确的上下文中评估的'方法字符串':
before_save 'self.format_phone_fields(....)'
另一种可能性:将您的字段名称存储为类变量并在您的实例中访问该字段,然后您可以使用before_save:format_phone_fields