我有几个不同的acts_as_。。。我想在应用程序中使用的自定义类方法。我希望这些方法的代码在app/modules目录中的文件中。
我一直没能把这件事做好。
例如,我有一个文件:app/modules/acts_as_lockable
module ActsAsLockable
def acts_as_lockable
before_create :set_lock
include InstanceMethods
end
module InstanceMethods
protected
def set_lock
now = Time.now.to_s
self.lock = Digest::SHA1.hexdigest(now)
end
end
end
ActiveRecord::Base.extend ActsAsLockable
在应用程序.rb
config.autoload_paths += %W(#{config.root}/app/modules)
当我试图加载一个调用acts_as_lockable的模型时,我会得到以下错误:
NameError:未定义的局部变量或方法`acts_as_lockable'
我的猜测是,我不应该自动加载模块文件夹,因为当我扩展ActiveRecord时,它已经加载了?有别的办法吗?我希望能够在开发过程中更改文件,而无需重新启动服务器,但这更像是一种需要。
我认为您的想法是错误的。
您正在将此模块添加到加载路径,
但只有当你说;
require 'acts_as_lockable'
或
ActsAsLockable
我建议您永远不要真的想在代码中说出这两个。
你正在寻找的正确范例是"初始化器"。
我建议您创建一个名为"config/ininitializers/acts_as_lockable.rb"的文件
在这个文件中,你可以包括整个代码,
或者只包括require 'acts_as_lockable'
通常我会把这样的东西放在libs目录中
确保lib在加载路径中
**config/application.rb**
config.autoload_paths += %W(#{config.root}/lib)
**lib/acts_as_lockable.rb**
module ActsAsLockable
def acts_as_lockable
before_create :set_lock
include InstanceMethods
end
module InstanceMethods
protected
def set_lock
now = Time.now.to_s
self.lock = Digest::SHA1.hexdigest(now)
end
end
end
则在初始值设定器中
**config/ininitializers/acts_as_lockable.rb**
require 'acts_as_lockable'
ActiveRecord::Base.extend ActsAsLockable
问题是ruby自动加载机制是一个懒惰的过程:当在代码中使用像ActsAsLockable这样的常量时,它会在autoload_path中查找一个名为acts_as_lockable.rb的文件。由于您从未实际使用ActsAsLockable,因此该文件从未加载。你可以做(虽然不是非常漂亮):
ActsAsLockable
class MyModel < ActiveRecord::Base
acts_as_lockable
...
end
我认为acts_as_*模式将被用作插件和宝石,以便轻松地将功能集成到代码中。当您将插件和gem集成到项目中时,它们应该处于最终状态,因此您不需要为开发模式重新加载功能。
我希望这能有所帮助。