我正在开发一个遗留的 Oracle 数据库,该数据库具有稍微奇怪的表命名约定,其中每个列名都以表首字母为前缀 - 例如policy.poli_id。

为了使该数据库更易于使用,我有一个方法 set_column_prefix ,它为删除了前缀的每列创建访问器。IE:

# Taken from wiki.rubyonrails.org/rails/pages/howtouselegacyschemas
class << ActiveRecord::Base
  def set_column_prefix(prefix)
    column_names.each do |name|
      next if name == primary_key

      if name[/#{prefix}(.*)/e]
        a = $1

        define_method(a.to_sym) do
          read_attribute(name)
        end

        define_method("#{a}=".to_sym) do |value|
          write_attribute(name, value)
        end

        define_method("#{a}?".to_sym) do
          self.send("#{name}?".to_sym)
        end

      end
    end
  end
end

它位于我的 lib/ 目录中的文件 (insoft.rb) 中,并且需要从 Rails::Initializer.run 块之后的 config/environment.rb 中获取。

这在开发中运行良好,但是当我尝试在生产模式下运行应用程序时,我在所有模型中都会收到以下错误:

dgs@dgs-laptop:~/code/voyager$ RAILS_ENV=production script/server 
=> Booting Mongrel
=> Rails 2.3.2 application starting on http://0.0.0.0:3000
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:1964:in `method_missing': 
undefined method `set_column_prefix' for #<Class:0xb3fb81d8> (NoMethodError)
    from /home/dgs/code/voyager/app/models/agent.rb:16

此错误是由 config/environments/Production.rb 中的“config.cache_classes = true”行触发的。如果我将其设置为 错误的, ,然后 Rails 将启动,但不会缓存类。我猜这使得 Rails 在运行初始化程序块之前缓存所有模型

如果我将 'require "insoft.rb'" 移至 Rails::Initializer.run 块开始之前,则会出现错误,因为 ActiveRecord 尚未初始化:

usr/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:443:in `load_missing_constant': uninitialized constant ActiveRecord (NameError)
    from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:80:in `const_missing'
    from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:92:in `const_missing'
    from /home/dgs/code/voyager/lib/insoft.rb:1

我应该在哪里包含这个自定义库和 set_column_prefix 方法,以便在模型缓存之前但在所有 activerecord 文件加载之后拾取它?

干杯

戴夫·斯迈利

有帮助吗?

解决方案

我应该在哪里包含这个自定义库和 set_column_prefix 方法,以便在模型缓存之前但在所有 activerecord 文件加载之后拾取它?

尝试设置一个 初始化器. 。您可以使用猴子补丁的内容将其命名为 config/initializers/insoft.rb :

class << ActiveRecord::Base
  def set_column_prefix(prefix)
    column_names.each do |name|
      next if name == primary_key

      if name[/#{prefix}(.*)/e]
        a = $1

        define_method(a.to_sym) do
          read_attribute(name)
        end

        define_method("#{a}=".to_sym) do |value|
          write_attribute(name, value)
        end

        define_method("#{a}?".to_sym) do
          self.send("#{name}?".to_sym)
        end

      end
    end
  end
end
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top