0

我有一个 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?'

我在动作包部分之后切断了跟踪,因为它真的很长,但我认为这是所有相关信息。

这是我的引擎类定义:

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

4

1 回答 1

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 
于 2011-10-07T20:38:47.293 回答