【问题标题】:Rails sometimes issues NoMethodError when calling an inherited method from an Engine controller从 Engine 控制器调用继承的方法时,Rails 有时会发出 NoMethodError
【发布时间】:2015-10-28 09:16:27
【问题描述】:

我正在编写一个包含一个主应用程序和一个可安装引擎的 Rails 应用程序,但我遇到了一些让我发疯的问题。

Rails 在从引擎控制器调用主应用控制器中定义的函数时随机发出 NoMethodError。

到目前为止,我已经在主应用程序中定义了一个控制器,引擎中的控制器从该控制器继承。下面是目录结构的总结,是“my_plugin”引擎的目录(代码也附在下面)。

我注意到,当 WEBrick 运行时,如果我只是“触摸”bar_controller.rb 文件(即不加修改地保存它),那么一切都会开始正常运行。似乎 Rails 有时在启动期间无法正确加载父类,并且触摸文件会使其重新加载所有内容(抱歉,我不知道 Rails 内部是如何工作的)。

我做错了什么?

app
|- controllers
   |- foo_controller.rb
...
plugins
| - my_plugin
        | - app
             | - controllers
                 | - my_plugin
                     | - application_controller.rb
                     | - bar_controller.rb

foo_controller.rb中的代码是:

class FooController < ActionController::Base  
    protect_from_forgery with: :null_session

    private
        def my_function
            #...
        end
end

另一方面,我的插件application_controller.rb 中的代码是:

module MyPlugin  
  #Inherit from main's app FooController
  class ApplicationController < ::FooController
  end
end

最后,我的插件bar_controller.rb中的代码是:

module MyPlugin
  class BarController < ApplicationController    
      def index
          #####################################################
          # The statement below issues NoMethodError until
          # I touch this file while WEBrick is running.
          #####################################################
          my_function
      end
  end
end

编辑

我注意到如果我在插件的application_controller.rb 中定义my_function(见下文)并且不从FooController 继承,问题仍然存在。所以看起来这个问题与应用程序类的继承无关。

module MyPlugin        
  class ApplicationController < ActionController::Base
      private
          def my_function
               #...
          end
  end
end

【问题讨论】:

    标签: ruby-on-rails-4 webrick


    【解决方案1】:

    我找到了自己的解决方案,我必须说 Rails 与引擎一起工作以及对愚蠢情况做出反应的方式非常令人失望。

    我已经在我的插件中创建了一个测试模型:

    require_dependency "my_plugin/application_controller"
    

    我手动创建了BarController,因此我没有写那行(我错误地依赖了“Rails 是魔法”的前提;Rails 对我来说不再是魔法)。现在,我的问题是:

    1. 如果 mountable Engines 被称为“isolated Rails applications”,为什么我必须改变为引擎编写代码的方式?为什么我必须明确告诉 Ruby 需要该依赖项?当我在主应用程序中编写控制器时,Rails 会“发挥作用”。为什么它在这里也不施展魔法呢?

    2. 有没有办法在 Rails 加载模块时自动加载此类依赖项?

    3. 如果需要依赖,为什么 Rails 在尝试从“未加载的类”继承时不会发出错误,而不是在尝试调用继承的方法时失败?

    编辑

    有关更多信息,请参阅GitHub 上的讨论。所有这些都与记录在 here 的 Rails 陷阱有关。

    【讨论】:

      猜你喜欢
      • 2023-03-14
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多