2014-07-03 71 views
14

這是一個棘手的解釋。我在另一個模塊命名空間的模塊,像這樣:儘管在文件中定義了文件,但無法自動從文件自動加載文件

# app/models/points/calculator.rb 
module Points 
    module Calculator 
    def self.included(base) 
     base.send(:include, CommonMethods) 
     base.send(:include, "Points::Calculator::#{base}Methods".constantize) 
    end 
    end 
end 

所以後來在其他類中的所有我需要做的是:

class User 
    include Points::Calculator 
end 

我指定在application.rb中這個目錄是autoloadable ...(即使我認爲鐵軌遞歸通過模型...)

config.autoload_paths += Dir[ Rails.root.join('app', 'models', "points") ] 

在開發環境,一切工作正常。當運行測試(生產ENV),我收到以下錯誤:

Unable to autoload constant Points::Calculator, expected /Users/pete/work/recognize/app/models/points/calculator.rb to define it (LoadError) 

其實我跟着這裏的建議來解決這個問題:在application.rb中明確要求calculator.rb Stop Rails from unloading a module in development mode

但是,爲什麼會發生這種情況?

我在ActiveSupport的dependencies.rb文件中插入了一些調試輸出,並注意到這個文件需要兩次。它第一次需要我可以看到這個常量確實被加載了。

但是第二次它所需的常量已被卸載,據Rails所知,但當實際的請求被調用時,ruby返回false,因爲ruby知道它已經要求它。然後,Rails拋出「無法自動加載常量」錯誤,因爲常量仍然不存在,並且ruby沒有「重新請求」該文件。

任何人都可以闡明爲什麼這可能會發生?

+0

從自動加載路徑丟失中刪除點有幫助嗎?它不應該是必需的 –

+0

是的,我已經試過它和沒有在自動加載路徑。同樣的問題。 –

+0

似乎有同樣的問題。非常討厭必須要求班級,因爲我有大約30多個這樣的班級。 – Kohanz

回答

0

Calculator應該是一個類被自動加載正確

module Points 
    class Calculator 
    ... 
    end 
end 
+0

對不起,我描述錯了,它是一個模塊中的一個模塊...我已經更新了上面的描述以更準確...模塊是否影響自動加載? –

+0

在這種情況下,我建議將該文件放在'lib'目錄而不是'app/models'中。 – infused

+1

lib是針對非應用程序特定的庫,因此我將這個應用程序/。然而,我可以看到把這個放在app/lib或者應用程序/關注點或應用程序/模型/關注目錄中的說法 –

7

的Rails增強紅寶石的恆定查找機制。在紅寶石

常量查找:

類似於method missing,一個Module#constant-missing被調用時爲恆定的基準未能得到解決。當我們提到一個恆定在一個給定的詞彙範圍,這是不變中搜索:

Each entry in Module.nesting 
Each entry in Module.nesting.first.ancestors 
Each entry in Object.ancestors if Module.nesting.first is nil or a module. 

當我們提到一個常量,Ruby的第一次嘗試根據發現它這個內置的查找規則。

紅寶石未能找到...軌道踢,並使用its own lookup convention及其哪些常量已經被加載(由紅寶石)的知識,Rails的覆蓋Module#const_missing加載缺失的常量,而無需顯式需要程序員的調用。

它自己的查找約定?

按照將常量映射到文件名的約定,對比Ruby的自動加載(它需要預先指定每個自動加載常量的位置)rails。

Points::Calculator # =>points/calculator.rb 

現在的恆定點::計算器,軌道檢索的自動加載路徑內的該文件路徑(即「點/ calculator.rb」),由所述autoload_paths配置中定義。

在這種情況下,rails會在其自動加載路徑中搜索文件路徑points/calculator,但無法找到文件,因此會顯示此錯誤/警告。

這個答案是從這個Urbanautomation blog摘要。

+5

確實,我看過這篇文章,並感謝您的解釋。但是,該文件存在並正確加載一次,但如上所述,我可以看到它需要兩次,並在第二次出現時,常量已被卸載。我不清楚你的解釋如何解決這個事實。 –

+3

你解決了這個問題嗎? – Joe