Rails中的动态常量定义

时间:2010-11-23 12:13:04

标签: ruby-on-rails ruby metaprogramming

我使用以下语法在Rails中的初始化程序中定义一个常量:

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

如果我启动控制台并编写

,它会起作用
MyModule::MYCONSTANT 

我按照预期收到foobar。

问题是,当我尝试在模型中调用它时,常量不存在。

D在哪里应该动态定义我的常量,它在我的模型中也可以使用?

如果我在lib / mymodule.rb中静态定义它,它可以工作,但我想在运行时定义一些常量。

3 个答案:

答案 0 :(得分:14)

如果你想保留config.cache_classes = false, 你可以把

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

进入application.rb中的以下块:

config.to_prepare do
MyModule.const_set('MYCONSTANT','foobar')
end

答案 1 :(得分:4)

在开发模式中自动加载可能是个问题吗?

为每个请求重新创建模型类,因此您需要一次又一次地创建常量。

问题会在生产模式中消失。您可以在开发模式下关闭自动加载,但这会强制您在代码中的每次更改后重新启动服务器。

请参阅config / environments / development.rb:config.cache_classes = false(更改为true)。

答案 2 :(得分:4)

当我试图做“动态常数”时,我偶然发现了这一点。

我的目标是能够将特定的数据库条目用作常量。 (一旦插入,该行将永远不会在特定实例上更改,但在不同实例上ID可能不同。)

我提出了一个可以应用于此案例的解决方案,具体取决于您尝试使用动态常量的原因。这是我的用例中的一个例子,但用其他东西替换属性定义相当容易。

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