Определение динамических констант в Rails - PullRequest
19 голосов
/ 23 ноября 2010

Я определяю константу в инициализаторе в Rails, используя следующий синтаксис:

MyModule.const_set('MYCONSTANT','foobar')

Это работает, если я запускаю консоль и пишу

MyModule::MYCONSTANT 

Я получаю foobarкак и ожидалось.

Проблема в том, что когда я пытаюсь вызвать ее в модели, константы там нет.

Где D должен динамически определять мою константу, чтобы она была доступна и в моеммодели?

Если я статически определяю его в моем lib / mymodule.rb, он работает, но я бы хотел определить некоторые константы во время выполнения.

Ответы [ 3 ]

14 голосов
/ 11 июля 2012

если вы хотите сохранить config.cache_classes = false, вы можете поместить

MyModule.const_set('MYCONSTANT','foobar')

в следующий блок в application.rb:

config.to_prepare do
MyModule.const_set('MYCONSTANT','foobar')
end
4 голосов
/ 30 сентября 2013

Я наткнулся на это, когда пытался создать «динамические константы».

Моя цель - использовать конкретную запись базы данных в качестве константы. (После вставки строка никогда не изменится на конкретном экземпляре, но идентификаторы могут отличаться в разных экземплярах).

Я придумал решение, которое может применяться к этому случаю в зависимости от того, почему вы пытаетесь иметь динамические константы. Вот пример в моем примере использования, но довольно легко заменить определение атрибута чем-то другим.

class MyModel < ActiveRecord::Base
  def self.MY_CONST
    @my_const ||= MyModel.find_by(code: 'my_const_code')
  end
end

А вот как я это проверил:

require 'test_helper'

class MyModelTest < ActiveSupport::TestCase
  test "mymodel constant defined" do
    assert_equal MyModel.find_by(code: 'my_const_code'), MyModel.MY_CONST
  end
end
4 голосов
/ 23 ноября 2010

Может быть, проблема в автозагрузке в режиме разработки?

Ваш класс модели воссоздается для каждого запроса, поэтому вам придется создавать константу снова и снова.

Проблема просто исчезнетв производственном режиме.Вы можете отключить автозагрузку в режиме разработки, но это заставит вас перезапускать сервер после каждого изменения в вашем коде.

См. Config / environment / development.rb: config.cache_classes = false (изменить на true).

...