从引擎控制器

时间:2015-10-28 09:16:27

标签: ruby-on-rails-4 webrick

我正在编写一个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

修改

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

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

1 个答案:

答案 0 :(得分:1)

我发现自己是解决方案,我必须说Rails与引擎配合使用并对愚蠢情况做出反应非常令人失望。

我在我的插件中使用rails scaffolding 创建了一个测试模型,我注意到生成的控制器在主应用程序的控制器中没有的文件顶部有一个额外的代码行:

require_dependency "my_plugin/application_controller"

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

  1. 如果可安装的引擎被称为“隔离的Rails应用程序”,为什么我必须改变编写引擎代码的方式?为什么我必须明确告诉Ruby要求依赖?当我在主应用程序中编写控制器时,Rails会做“所有魔术”。为什么它也没有在这里发挥作用呢?

  2. 当Rails加载模块时,有没有办法自动加载这些依赖项?

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

  4. 修改

    有关详细信息,请参阅GitHub上的此讨论。所有这些都与Rails记录here有关。