Проблема с зависимостями Rails при работе в производственном режиме

StackOverflow https://stackoverflow.com/questions/1084851

Вопрос

Я работаю над устаревшей базой данных 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

Это находится в файле (insoft.rb) в моей библиотеке / каталоге и требуется из моего config /environment.rb после блока Rails::Initializer.run.

Это прекрасно работало в процессе разработки, но когда я пытаюсь запустить приложение в рабочем режиме, я получаю следующую ошибку во всех моих моделях:

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.cache_classes = true' в config/environments/production.rb.Если я установлю это на ложь, тогда 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 с содержимым вашего патча monkey:

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