无法调用内部方法中的关联缺失。救命!

时间:2011-01-20 03:49:08

标签: ruby-on-rails ruby-on-rails-3

我有一个简单的acts_as样式模块,它包含在ActiveRecord :: Base中。本单元的目的是:

  1. 将has_one关联添加到ActiveRecord模型

  2. 向实例添加缺少的方法,将任何缺少的方法定向到关联的实例。

  3. 以下是示例模块:

    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
    

1 个答案:

答案 0 :(得分:2)

Erik - 如果我没记错的话,AR使用method_missing来定义类的属性访问器等,例如:它们不是硬编码的。它们存储在实例变量中,但.id和.id =方法是即时定义的。因此,我建议您定义一种方法来匹配您想要引用相关接口的缺失方法。