2010-11-02 138 views
73

我把文件名g.rb在側Rails.root/lib文件夾 文件內容是這樣的:在Rails 3中添加的lib到「config.autoload_paths」不自動載入我的模塊

module Google 
end 

然後,添加

config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs) 

Rails.root/config/application.rb

然而,當我嘗試從rails console調用谷歌,則拋出異常。只有當我執行require 'google'時,例外情況纔會消失。 爲什麼?我的文件不應該自動加載,不應該在沒有任何額外require聲明的情況下訪問模塊?

回答

112

嗯,我發現了一件有趣的事情。爲了讓Rails自動加載我的類,類名應該符合文件名和文件夾結構。 例如,如果我想讓Google模塊自動加載,我必須將其置於google.rb之下,直接位於/ lib下(如果指定自動加載/ lib)。 如果我要自動加載Google::Docs,那麼我要麼地方這裏面google.rbgoogle/docs.rb

+6

所以這是一個錯誤或公約? – Blankman 2010-11-22 17:02:08

+8

我相信這是慣例。 Rails使用不變的名稱,並使路徑離開它們。 ::變成/爲此目的。所以Google :: Docs變成了google/docs.rb。你可以辯論這個的用處,但這是我對當前功能的理解。 – 2011-01-26 22:17:39

+3

這不是一個慣例,它是Ruby解釋器尋找東西的方式,據我所知 – Ghoti 2011-05-09 16:42:58

1

我剛纔所面臨的同樣的問題,我的「解決方案」(或者說解決方法)是手工需要從Rails的每一個需要的文件。 root/lib在我的application.rb中。

require 'lib/message' 
require 'lib/store' 
require 'lib/vault/vault.rb' 
require 'lib/custom_loggers' 

module MyApplication 
    class Application < Rails::Application 

我的下一步是按照您提到的方式對模塊文件夾中的文件進行分類。

+1

斯蒂芬G有一個很好的答案。 – Mirko 2011-01-31 19:58:31

+0

嗨@morbaq,今天我有同樣的問題,你的解決方案完美地工作,只是想說謝謝:D – sameera207 2011-10-29 05:26:57

24

這是因爲自動加載的點是而不是以預先要求所有的東西(啓動罰分)。類是根據需要/引用加載的。爲了做到這一點,你需要一些方法來知道在哪裏尋找課程。否則,您將不得不提前加載autoload目錄中的每個文件,以查看聲明瞭哪些類。這是一種折衷,但是事先要求一切(如marbaq所暗示的)不是自動加載的。 您可以使用Ruby提供的autoload命令,該命令帶有兩個參數,要加載的模塊(符號化,即:Google),第二個參數是文件名,如果lib處於中,則爲g.rb你的加載路徑($ :)。查看Ruby文檔的自動加載。

+1

順便說一句,約定你應該只需要重命名lib/g.rb到lib/google.rb並在路上。 – 2015-08-13 00:21:46

27

我有一個類似的問題,讓我的模塊在Heroku上運行。除了Stephen C提出的自動加載命名約定之外,由於Heroku上的Rails生產環境假設threadsafe,因此我發現模塊代碼必須爲require'd(即使threadsafe已在我的production.rb配置文件中註釋掉了)在模塊上調用include之前,只要I require'd模塊文件開始工作。

require 'mymodule' 
include Mymodule 

請採取越來越模塊中的Heroku(生產)正確加載的主題一看this excellent article

+0

+1這應該是被接受的答案。鏈接應該有助於任何人和線程的安全性其實是我的問題。謝謝。 – 2011-11-09 11:58:10

-5

,我發現這個解決方案最近

配置/應用。RB

module AppName 
    class Application < Rails::Application 

    # Custom directories with classes and modules you want to be autoloadable. 
    config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')] 
    config.autoload_paths += Dir[Rails.root.join('app', 'lib', 'extensions')] 

    end 
end 

第一配置呼叫誘導軌自動加載應用程序/車型目錄 的所有子目錄所以現在我可以有/app/models/sub_directory/model.rb自動加載 (方便組織與大型代碼庫的應用程序)

第二配置呼叫引起導軌自動加載的lib/extensions目錄

希望這有助於

注:我相信這是軌道3特定