Ruby on rails 如何从应用程序/模块扩展ActiveRecord?
我有几种不同的表演。。。我想在我的应用程序中使用的自定义类方法。我希望这些方法的代码位于app/modules目录中的文件中 我一直无法让它工作 例如,我有一个文件:app/modules/acts\u as\u lockableRuby on rails 如何从应用程序/模块扩展ActiveRecord?,ruby-on-rails,ruby,ruby-on-rails-3,metaprogramming,extend,Ruby On Rails,Ruby,Ruby On Rails 3,Metaprogramming,Extend,我有几种不同的表演。。。我想在我的应用程序中使用的自定义类方法。我希望这些方法的代码位于app/modules目录中的文件中 我一直无法让它工作 例如,我有一个文件:app/modules/acts\u as\u lockable module ActsAsLockable def acts_as_lockable before_create :set_lock include InstanceMethods end module I
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
和在application.rb中
config.autoload_paths += %W(#{config.root}/app/modules)
当我尝试加载一个调用acts_as_lockable的模型时,我得到以下错误:
NameError:未定义的局部变量或
方法“作为可锁定的”
我猜我不应该自动加载modules文件夹,因为当我扩展它时,ActiveRecord已经被加载了?还有别的办法吗?我希望能够在开发过程中更改文件,而无需重新启动服务器,但这更像是一种需要。问题是ruby自动加载机制是一个惰性的过程:当代码中使用ActsAsLockable之类的常量时,它会在自动加载路径中查找名为acts_as_lockable.rb的文件。由于您从未实际使用ActsAsLockable,因此永远不会加载该文件。你可以做(虽然不是非常漂亮):
可执行锁定
类MyModel
我认为acts_as_*模式可以作为插件和gem使用,以方便地将功能集成到代码中。插件和gem应该在您将它们集成到项目中时处于最终状态,这样您就不需要为开发模式重新加载功能
我希望这能有所帮助。我认为你的想法是错误的 您正在将此模块添加到加载路径 但只有当你说:
require 'acts_as_lockable'
或
我建议你永远不要在你的代码里说这两个词
您正在寻找的正确范例是“初始值设定项”
我建议您创建一个名为“config/initializers/acts_as_lockable.rb”的文件
在这个文件中,您可以包含整个代码
或者只包含一个require'acts\u as\u lockable'
通常我会将类似的内容保存在libs目录中
确保lib位于加载路径中
**config/application.rb**
config.autoload_paths += %W(#{config.root}/lib)
**lib/act_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
require 'acts_as_lockable'
ActiveRecord::Base.extend ActsAsLockable
然后在初始值设定项中
**config/initializers/act_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
require 'acts_as_lockable'
ActiveRecord::Base.extend ActsAsLockable
谢谢你,你的工作很有魅力。我意识到这可能不是最实际的解决方案,但出于某种原因,我讨厌在我的模型中看到include语句。