我有一个简单的acts_as样式模块,它包含在ActiveRecord :: Base中。本单元的目的是:
将has_one关联添加到ActiveRecord模型
向实例添加缺少的方法,将任何缺少的方法定向到关联的实例。
以下是示例模块:
module TestModule
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def test_me_out
has_one :text_page
send(:include, InstanceMethods)
end
end
module InstanceMethods
def method_missing(method, *args, &block)
Rails.logger.debug "#{method}"
#text_page.send(method, *args, &block)
text_page
end
end
end
我可以在AR模型中使用它......
Class Page < ActiveRecord::Base
test_me_out
end
问题是,如果运行模块中的* method_missing *方法,它会立即导致method_missing中的“堆栈级太深”错误。
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
...
缺少的方法是'id'?!?您会注意到我已经注释掉了将缺少的方法发送到关联类的示例代码行 - text_page.send(method,* args,&amp; block) - 因为只需调用关联 - text_page - 就足够了触发堆栈级别太深的错误。
有人能发现错误吗?
PS。当然,这是实际模块和用例的简化示例,但这说明了错误,并且失败了。
解
非常感谢Alex的拯救。使用方法缺失块动态生成ActiveRecord Id。以下代码可以正常工作,因为它将:缺少的id方法传递给super:
def method_missing(method, *args, &block)
if method != :id && text_page.respond_to?(method)
text_page.send(method, *args, &block)
else
super
end
end
答案 0 :(得分:2)
Erik - 如果我没记错的话,AR使用method_missing来定义类的属性访问器等,例如:它们不是硬编码的。它们存储在实例变量中,但.id和.id =方法是即时定义的。因此,我建议您定义一种方法来匹配您想要引用相关接口的缺失方法。