我正在编写一个Rails插件(让我们称之为Foo)。 我希望它在控制器中提供“bar”类功能,以便我可以这样做:
class ApplicationController
bar ...
end
bar
是通过插件加载文件vendor / plugins / foo / init.rb定义的。像
class ActionController::Base
def self.bar
...
end
end
问题是其他一些插件(在我的情况下是ResourceController)可能会在 foo之前加载并访问ApplicationController。
所以会发生的事情是,在插件'foo'之前加载了ApplicationController并且因为没有'bar'定义 YET 而失败。
那么......我如何正确使其有效?
我注意到许多其他扩展ActionController的插件(例如inherited_resources,resource_controller)正在做同样的事情,所以看起来是谁首先加载以决定它是否失败或工作。
我知道我可以将代码放在某个模块中,并在调用'foo'之前手动将模块添加到ApplicationController代码中。我不愿意,我喜欢'foo'的清洁。
我也不想做手册'要求'。插件本身应该自动加载:)
答案 0 :(得分:1)
您拥有的是经典的插件加载顺序问题。 Ryan Daigle在2007年就有了nice article。我将在这里总结一下这个建议:
# in RAILS_ROOT/config/environment.rb:
...
Rails::Initializer.run do |config|
# load Bar before Foo, then everything else:
config.plugins = [ :bar, :foo, :all ]
...
end
答案 1 :(得分:0)
据我了解,
ResourceController
在插件foo
之前加载,并尝试使用您在bar
中定义的foo
方法。
通常,在应用程序类之前加载gem和plugins。 (看看rails/railties/lib/initializer.rb
)。你能提供一个错误的堆栈跟踪,以便可以调试它。
另外,对于扩展课程,这似乎是一个更好的选择:
module ActionController
class Base
class << self
... # Class methods here
end
... # Instance methods here
end
end