рельсы 3.1 создание динамического контроллера - PullRequest
0 голосов
/ 25 сентября 2011

У меня есть гем Rails Engine, в котором я хочу динамически загрузить определение класса HomeController из инициализатора. Я могу правильно создать экземпляр класса, но когда я вызываю действие index, я получаю эту ошибку:

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?'

Я обрезал след после части actionpack, потому что он был действительно длинным, но я думаю, что это вся важная информация.

Вот мое определение класса двигателя:

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. если я создаю home_controller.rb в app / controllers в приложении или в геме так:

class HomeController < ApplicationController
end

тогда все работает нормально, и действие index отображается правильно, поэтому я уверен, что нет проблем с моими маршрутами, представлениями или контроллером приложения.

Любой свет, пролитый по этому вопросу, будет высоко оценен. редактировать выход

HomeController.view_paths.join " : "

есть

/home/chris/gems/my_gem/app/views : /home/chris/test_app/app/views

1 Ответ

0 голосов
/ 08 октября 2011

Я не уверен, откуда вы взяли "инициализатор" 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 
...