如何从app/modules扩展ActiveRecord?

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
Run Code Online (Sandbox Code Playgroud)

并在application.rb

config.autoload_paths += %W(#{config.root}/app/modules)
Run Code Online (Sandbox Code Playgroud)

当我尝试加载调用acts_as_lockable的模型时,我收到以下错误:

NameError:未定义的局部变量或方法`acts_as_lockable'

我的猜测是我不应该自动加载模块文件夹,因为我扩展它时已经加载了ActiveRecord?还有另一种方法吗?我希望能够在开发期间更改文件而无需重新启动我的服务器,但这更像是一种需要.

Mat*_*udy 7

我想你是以错误的方式思考这个问题.

您正在将此模块添加到加载路径,

但是如果你要么说它只会加载;

require 'acts_as_lockable'
Run Code Online (Sandbox Code Playgroud)

要么

ActsAsLockable
Run Code Online (Sandbox Code Playgroud)

我建议你永远不要在你的代码中说出其中任何一个.

您正在寻找的正确范例是"初始化程序".

我建议你创建一个名为"config/initializers/acts_as_lockable.rb"的文件

在此文件中,您可以包含整个代码,

或者只是包括一个 require 'acts_as_lockable'

通常我会在libs目录中保留这样的内容

确保lib在加载路径中

**config/application.rb**

config.autoload_paths += %W(#{config.root}/lib)
Run Code Online (Sandbox Code Playgroud)

**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
Run Code Online (Sandbox Code Playgroud)

然后在初始化器中

**config/initializers/acts_as_lockable.rb**

require 'acts_as_lockable'
ActiveRecord::Base.extend ActsAsLockable
Run Code Online (Sandbox Code Playgroud)