我正在编写一个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
答案 0 :(得分:1)
我发现自己是解决方案,我必须说Rails与引擎配合使用并对愚蠢情况做出反应非常令人失望。
我在我的插件中使用rails scaffolding 创建了一个测试模型,我注意到生成的控制器在主应用程序的控制器中没有的文件顶部有一个额外的代码行:
require_dependency "my_plugin/application_controller"
我手动创建了BarController
因此我没有写那条线(我错误地依赖于'Rails是魔术'的前提; Rails对我来说不再是魔术)。现在,我的问题是: