Rails 4:生产环境中不可能的超类不匹配异常

时间:2015-08-21 09:09:41

标签: ruby-on-rails-4 exception superclass rails-engines subclassing

我目前正在开发一个更大的rails应用程序,它使用引擎用于子应用程序,具有以下文件夹结构:

- app
  \- controllers
     \- global
        \- base_controller.rb
        \- configurations_controller.rb
     \- application_controller.rb
- ...
- engines
  \- engine_1
     \- app
        \- controllers
           \- engine_1
              \- application_controller.rb
              \- global
                 \- base_controller.rb
                 \- configurations_controller.rb

- ...

控制器的设置如下:

# app/controllers/global/base_controller.rb
class Global::BaseController < ApplicationController
end


# app/controllers/global/configurations_controller.rb
class Global::BaseController < Global::BaseController
end


# engines/engine_1/app/controllers/engine_1/application_controller.rb
module Engine1
  class ApplicationController < ::ApplicationController
  end
end


# engines/engine_1/app/controllers/engine_1/global/base_controller.rb
require_dependency "engine_1/application_controller"

module Engine1
  class Global::BaseController < ApplicationController
  end
end


# engines/engine_1/app/controllers/engine_1/global/configurations_controller.rb

module Engine1
  class Global::ConfigurationsController < Global::BaseController
  end
end

我的路线档案

# config/routes.rb
Rails.application.routes.draw do
  namespace :global do
    resource :configuration, only: [:show, :update]
  end

  mount Engine1::Engine, at: '/engine_1', as: :engine_1
end


# engines/engine_1/config/routes.rb
Engine1::Engine.routes.draw do
  namespace :global do
    resource :configuration, only: [:show, :update]
  end
end

在开发环境中,一切都按预期工作。但是在生产环境中,当应用程序启动并且正在急切加载类时,当Superclass mismatch尝试加载模块Global::BaseController中的Global::ConfigurationsController时,我会收到Engine1例外

我在重命名Engine1::Global::BaseController时克服了问题(暂时),但我不明白为什么它只在生产模式下工作?

2 个答案:

答案 0 :(得分:0)

当你在Rails中进行生产时,控制器的命名空间要严格得多。 Rails期望直接文件夹路径。如果您不希望这样做,那么您应该使用范围,例如:

scope :path => "account" do
  resources :users
end 

答案 1 :(得分:0)

当重新定义类时会发生Superclass mismatch错误。根据您的问题,错误在BaseController上。这是我的理论,看看你发布了什么。 BaseController被定义多次,因此当加载此代码时,BaseController是不明确的:

module Engine1
  class Global::ConfigurationsController < Global::BaseController
  end
end

看起来在加载时,BaseController现有2个定义。

# app/controllers/global/base_controller.rb
class Global::BaseController < ApplicationController
end


# app/controllers/global/configurations_controller.rb
class Global::BaseController < Global::BaseController
end

那么应该加载哪个BaseController?对你来说很明显应该在这里做些什么,而且我想我明白你要为你的配置增加一个间接级别。但是Rails在加载时将这两个定义视为相同的名称,并抛出超类错误。

这些是我对你的问题的看法。我很好奇你的想法。