2017-01-05 56 views
4

在我們的app目錄中,我們希望一些子目錄包含命名空間類,一些子目錄包含頂級類。例如:'app`目錄中的命名空間

  • app/models/user.rb限定::User
  • app/operations/foo.rb限定::Operations::Foo
  • app/operations/user/foo.rb限定::Operations::User::Foo

我們application.rb包含以下配置:

config.paths = Rails::Paths::Root.new(Rails.root) 
config.paths.add 'app/models', eager_load: true 
config.paths.add 'app', eager_load: true 

這在大多數情況下都可以正常工作,但有時在開發模式下,並且Rails的自動重載打開時,會導致加載錯誤的類。例如::User被誤認爲Operations::User,反之亦然。

有沒有辦法配置這種行爲,使其工作沒有任何錯誤?

如果不是,我能想到的唯一解決方法是爲appapp_namespaced行創建「名稱空間」類的第二個目錄。否則app/namespaced,因爲應用程序級代碼應該位於app之內。但是這些對我來說看起來很醜陋。

編輯:由@dgilperez問一個小例子:

# app/models/user.rb 
class User 
end 

# app/models/group.rb 
class Group 
    def some_method 
    # Since we're in a top-level namespace, User should always 
    # resolve to ::User. But, depending on some seemingly random 
    # factors, it sometimes resolves to Operations::User. 
    User.new 
    end 
end 

# app/operations.rb 
module Operations 
end 

# app/operations/user/create.rb 
module Operations::User 
    class Create 
    def some_method 
     # Here, as expected, I need to prefix with "::" as 
     # 'User' would refer to the module we're currently in. 
     # That's fine and works. 
     ::User.new 
    end 
    end 
end 
+1

爲[常量時不會丟失]中你可以使用完全合格的常量或'require_dependency'(http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#when-constants-aren-t-錯過) – Stefan

+0

你可以粘貼類的定義嗎?並且引起混淆的代碼(呼叫和位置) – dgilperez

+0

感謝您查看此@dgilperez,我剛剛添加了一個小例子。 – Remo

回答

0

是的,這是Rails的自動裝填的缺點。默認情況下,它會加載/app中的所有內容,但第一級目錄結構不是名稱的一部分。這是app/models/user.rb可以定義User,不要求它是Models::User

您不需要弄亂加載路徑。這裏提供了幾種方法/解決方法。

  1. 在我當前的項目中,我們只加了兩個namespacing目錄。也就是說,如果我們想定義ServiceObjects::User::Import,我們把它變成app/service_objects/service_objects/user/import.rb

  2. 我個人比較喜歡這種方法,它是把一個變化的所有「非標」的東西爲app/lib(可app/custom或任何你想要的) 。這樣,目錄名就沒有奇怪的重複,並且所有的自定義代碼都很好地包含在內。