2015-04-15 119 views
5

鑑於以下控制器的結構:Rails模塊將範圍

# application_controller.rb 
class ApplicationController < ActiveController::Base; end 

# pages_controller.rb 
class PagesController < ApplicationController; end 

# admin/application_controller.rb 
module Admin 
    class ApplicationController < ::ApplicationController; end 
end 

# admin/pages_controller.rb 
module Admin 
    class PagesController < ApplicationController; end 
end 

人們會預期Admin::PagesControllerAdmin::ApplicationController繼承它。但我注意到它有時從::ApplicationController繼承。

所以我決定不冒這個險,並在/admin改變所有控制器的聲明,專門針對Admin::ApplicationController

# admin/pages_controller.rb 
module Admin 
    class PagesController < Admin::ApplicationController; end 
end 

好這樣的作品,但我知道這是擺在首位正確的。爲什麼Rails有時會從錯誤的控制器繼承?

Admin::PagesController有時ApplicationController而不是Admin::ApplicationController繼承,儘管在同一module Admin

+0

我也遇到過類似的問題! – Hardik

回答

4

在這裏的問題均爲是Rails的開發模式代碼加載:在一般的代碼,當你嘗試做一些具有恆定加載(例如來自它的子類)並且該常量不存在。這導致調用const_missing,並且rails使用它來嘗試加載該類(有關詳細說明,請參閱the guide)。

如果再ApplicationController中也沒有聯繫:: ApplicationController中既不存在,當你訪問你的管理頁面控制器紅寶石會打的const_missing並嘗試加載管理/ application_controller.rb

但是,如果ApplicationController中已經被加載然後紅寶石不會火const_missing,因爲它完全合法的管理模塊中的類從頂層的東西繼承。

正如你所說的解決方案是明確你是從什麼繼承。我個人在我自己的應用程序中使用Admin::BaseController作爲基類。

+0

它在生產中的行爲是否相同? – firedev

+0

@Nick在生產中,所有東西都是先裝入的,所以我希望不會,但我想如果文件按特定順序裝入,它仍然可能發生 - 我不知道是否有軌道試圖避免這種情況。 –

1

另一種選擇是使用require_dependency到尖軌正確的文件:

# admin/application_controller.rb 

require_dependency 'admin/application_controller' 

module Admin 
    class PagesController < ApplicationController 
    end 
end 
+0

我想在這種情況下,最好使用像'AdminController'這樣的唯一名稱或像'Admin :: ApplicationController'這樣的顯式狀態範圍 – firedev