我有一个现在看起来像这样的模型:
class Logo < ActiveRecord::Base
include ImageManipulation
...
end
ImageManipulation
是一个名为image_manipulation.rb
的库,位于/lib/
我可以毫无问题地使用该模型,但今天我必须通过rails控制台进行一些操作,当试图做Logo.delete_all
,我收到了这个错误:
NameError: uninitialized constant Logo::ImageManipulation
所以,我改变模型看起来像这样:
require 'image_manipulation'
class Logo < ActiveRecord::Base
include ImageManipulation
...
end
我的问题是......当我想在rails控制台中使用Logo模型时,为什么需要这些,但是在启动rails s
并通过我的应用程序操作模型时不需要?
答案 0 :(得分:0)
我建议rails s
在开发模式和图书馆位置找到的自动加载类中开始。通过rails console
运行应用时,此自动加载可能不会发生相同的程度。
答案 1 :(得分:0)
这是因为您的自动加载设置。
当您加载Rails控制台时,Rails不会立即require
您应用中的每个文件,因为这需要很长时间。相反,它使用&#34;延迟加载&#34; - 在实际需要它之前,它不会将类加载到内存中。
这种方法的工作方式是,当您在代码中使用常量(即类或模块)时,解释器还没有看到它,它将智能地猜测它需要加载哪个文件找到该常量的代码。例如。对于User
,它会查找名为user.rb
的文件,对于ImageManipulation
,它会查找image_manipulation.rb
,并查找名称空间常量,例如Image::Manipulation
它会查找image/manipulation.rb
。
它在哪里查找这些文件?在您的&#34;自动加载路径&#34;中,这是存储在Rails应用的config
设置中的目录列表。因此,对于文件user.rb
,它会查找app/models/user.rb
,app/controllers/user.rb
,app/helpers/user.rb
等,直到a)它找到一个文件并加载它或b)它用完的地方到看,在这种情况下它会引发NameError
。
因此,有两种情况需要明确require
文件:
ImageManipulation
在Rails无法自动识别的文件中定义(即名为image_manipulation.rb
的文件。)image_manipulation.rb
不在自动加载路径中的目录中。默认情况下,您的autoload_paths
包含所有标准app
目录,例如models
和controllers
,但不包含lib
(据我所知......它可能取决于你的Rails版本)。因此,如果您希望能够自动加载ImageManipulation
,则应将其置于可自动加载的位置,或将lib
添加到自动加载路径,方法是将以下行添加到config/application.rb
:
config.autoload_paths.push(Rails.root.join("lib"))
我不知道为什么ImageManipulation
在rails s
下被自动加载,但不在rails c
下,但我怀疑你是否正在运行这两个rails命令在不同的环境下(例如,一个处于开发模式,另一个处于生产环境中),并且环境具有不同的自动加载设置。尝试在您的应用目录中搜索autoload
或autoload_paths
,看看您是否能发现任何异常情况。