2013-11-20 158 views
0

我有一個模型,現在看起來是這樣的:在Rails模型中包含一個lib - 是否需要「需要」?

class Logo < ActiveRecord::Base 
    include ImageManipulation 
    ... 
end 

ImageManipulation是一個名爲image_manipulation.rb庫,位於/lib/我可以沒有任何問題的模式工作,但是今天我不得不這樣做通過一些操作軌道控制檯,並嘗試做Logo.delete_all的時候,我得到這個錯誤:

NameError: uninitialized constant Logo::ImageManipulation 

所以,我改變我的模型看起來像這樣:

require 'image_manipulation' 
class Logo < ActiveRecord::Base 
    include ImageManipulation 
    ... 
end 

我的問題是......爲什麼當我想在軌道控制檯中使用Logo模型時需要這些必要條件,但在啓動rails s並通過我的應用程序操縱模型時沒有必要?

回答

0

我建議rails s開始在開發模式和自動加載類庫位置中找到的東西。當通過rails console運行應用程序時,此自動加載可能不會發生在相同的程度。

0

這是因爲您的自動加載設置。

加載Rails控制檯時,Rails將不會立即require應用程序中的每個文件,因爲這需要很長時間。相反,它使用「延遲加載」 - 它不會將類加載到內存中,直到實際需要它爲止。

這種方式的工作原理是,當您在代碼中使用常量(即類或模塊)時,解釋器還沒有看到它,它會智能猜測它需要加載哪個文件找到那個常量的代碼。例如。對於User,它將查找名爲user.rb的文件,對於ImageManipulation,它將查找image_manipulation.rb,並且對於命名空間常量,例如, Image::Manipulation它會尋找image/manipulation.rb

它在哪裏查找這些文件?在您的「自動加載路徑」中,這是存儲在您的Rails應用程序的config設置中的目錄列表。因此,對於文件user.rb,它會尋找app/models/user.rb,app/controllers/user.rb, app/helpers/user.rb等,直到a)它找到一個文件並加載它或b)它用完的地方看,在這種情況下,它會引起NameError

因此,有兩種情況下,你需要require明確的文件:(即一個名爲image_manipulation.rb

  1. ImageManipulation在其名稱的Rails無法自動找出一個文件中定義
  2. image_manipulation.rb不在自動加載路徑中的目錄中。

默認情況下,您的autoload_paths包括所有的標準app目錄,如modelscontrollers,但確實不包括lib(據我所知......這可能取決於你的Rails的版本)。所以,如果你想成爲能夠自動加載ImageManipulation你應該把它的地方它能夠自動載入,或通過添加以下行來config/application.rb添加lib到您的自動加載路徑:

config.autoload_paths.push(Rails.root.join("lib")) 

我不知道爲什麼ImageManipulation是在rails s下自動加載,但不在rails c下,但我懷疑你在不同的環境下運行兩個rails命令(例如一個處於開發模式,另一個處於生產環境),而且環境具有不同的自動加載設置。嘗試搜索您的應用程序目錄中的autoloadautoload_paths並查看是否可以發現任何異常。