tan*_*man 6 ruby metaprogramming ruby-on-rails extend ruby-on-rails-3
我有几个不同的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
并在application.rb
config.autoload_paths += %W(#{config.root}/app/modules)
当我尝试加载调用acts_as_lockable的模型时,我收到以下错误:
NameError:未定义的局部变量或方法`acts_as_lockable'
我的猜测是我不应该自动加载模块文件夹,因为我扩展它时已经加载了ActiveRecord?还有另一种方法吗?我希望能够在开发期间更改文件而无需重新启动我的服务器,但这更像是一种需要.
我想你是以错误的方式思考这个问题.
您正在将此模块添加到加载路径,
但是如果你要么说它只会加载;
require 'acts_as_lockable'
要么
ActsAsLockable
我建议你永远不要在你的代码中说出其中任何一个.
您正在寻找的正确范例是"初始化程序".
我建议你创建一个名为"config/initializers/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/initializers/acts_as_lockable.rb**
require 'acts_as_lockable'
ActiveRecord::Base.extend ActsAsLockable