0

初期化子からHomeControllerクラス定義を動的にロードしたいRailsEnginegemがあります。クラスを正しくインスタンス化できますが、インデックスアクションを呼び出すと、次のエラーが発生します。

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

4

1 に答える 1

0

DSL「イニシャライザー」をどこから入手するかはわかりませんが...問題が発生しているようです。new()では実行されません

これはRails3.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 に答える