我有一个Rails Engine gem,我想从初始化器动态加载HomeController类定义。我可以正确地实例化该类,但是当我去调用索引操作时,我收到此错误:
TypeError in HomeController#index
can't convert nil into String
Rails.root: /home/chris/test_app
Full Trace:
actionpack (3.1.0) lib/action_view/template/resolver.rb:16:in `<<'
actionpack (3.1.0) lib/action_view/template/resolver.rb:16:in `build'
actionpack (3.1.0) lib/action_view/template/resolver.rb:127:in `find_templates'
actionpack (3.1.0) lib/action_view/template/resolver.rb:45:in `find_all'
actionpack (3.1.0) lib/action_view/template/resolver.rb:76:in `cached'
actionpack (3.1.0) lib/action_view/template/resolver.rb:44:in `find_all'
actionpack (3.1.0) lib/action_view/path_set.rb:21:in `find_all'
actionpack (3.1.0) lib/action_view/path_set.rb:20:in `each'
actionpack (3.1.0) lib/action_view/path_set.rb:20:in `find_all'
actionpack (3.1.0) lib/action_view/path_set.rb:19:in `each'
actionpack (3.1.0) lib/action_view/path_set.rb:19:in `find_all'
actionpack (3.1.0) lib/action_view/path_set.rb:29:in `exists?'
actionpack (3.1.0) lib/action_view/lookup_context.rb:94:in `template_exists?'
我在动作包部分之后剪掉了痕迹,因为它真的很长,但我认为这是所有相关的信息。
这是我的Engine类定义:
module MyGem
class Engine < Rails::Engine
initializer 'my_gem.load_middleware' do |app|
home_controller = create_controller 'HomeController'
end
def create_controller(class_name, &block)
klass = Class.new ApplicationController, &block
Object.const_set class_name, klass
return klass
end
end
end
这是我将根路径设置为home #index。如果我在应用程序或gem中的app / controllers中创建一个home_controller.rb,如下所示:
class HomeController < ApplicationController
end
然后一切正常,索引操作正确呈现,所以我确信我的路由,视图或应用程序控制器没有问题。
对此问题的任何亮点都将不胜感激。 修改的
的输出 HomeController.view_paths.join " : "
是
/home/chris/gems/my_gem/app/views : /home/chris/test_app/app/views
答案 0 :(得分:0)
我不确定你从哪里获得DSL“初始化程序”......但这似乎会导致问题。它不会在new()
上执行这似乎对我在Rails 3.0.7中起作用:
module MyGem
class Engine < Rails::Engine
def initialize
home_controller = create_controller 'HomeController'
end
# this doesn't seem to do anything...
#
# initializer 'my_gem.load_middleware' do |app|
# home_controller = create_controller 'HomeController'
# end
def create_controller(class_name, &block)
klass = Class.new ApplicationController::Base , &block # shouldn't this be ApplicationController::Base ?
# Object.const_set class_name, klass # module of superclass is ApplicationController, not Object
ApplicationController.const_set(class_name, klass) # name of the module containing superclass
puts "Klass created! : #{Object.constants}"
return klass
end
end
end
并运行代码:
h = MyGem::Engine.new
Klass created! : [:Object, :Module, :Class, :Kernel, :NilClass, :NIL, :Data, :TrueClass, :TRUE, :FalseClass, :FALSE, :Encoding ... :BasicObject]
=> #<MyGem::Engine:0x00000006de9878>
> ApplicationController.const_get("HomeController")
=> ApplicationController::HomeController