2013-11-20 112 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并查看是否可以发现任何异常。