2010-11-23 19 views
15

estoy definiendo una constante en un inicializador en Rails utilizando la siguiente sintaxis:definición constante dinámica en los carriles

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

Funciona, si comienzo a una consola y escribir

MyModule::MYCONSTANT 

recibo foobar como se esperaba

El problema es que, cuando trato de llamarlo en un modelo, la constante no está allí.

¿Dónde debería definir dinámicamente mi constante que también puede estar disponible en mis modelos?

Si lo defino estáticamente en mi lib/mymodule.rb funciona pero me gustaría definir algunas constantes en tiempo de ejecución.

+0

Usted hizo una errata: MY_CONSTANT vs MYCONSTANT. ¿Es solo un error en la pregunta, o ese es el problema en tu código? – Arsen7

+0

error en la pregunta, ¡gracias! –

Respuesta

3

Tal vez la carga automática en el modo de desarrollo es el problema?

Su clase de modelo se recrea para cada solicitud, por lo que tendrá que crear la constante una y otra vez.

El problema simplemente desaparecería en el modo de producción. Puede desactivar la carga automática en modo de desarrollo, pero esto le obligará a reiniciar el servidor después de cada cambio en su código.

Ver config/environments/development.rb: config.cache_classes = false (cambiar a verdadero).

+0

perfecto, ese era el problema. Gracias :-) –

12

si desea mantener config.cache_classes = false, puede poner

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

en bloque siguiente en application.rb:

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

He tropezado con esto como yo estaba tratando de hacer " constantes dinámicas ".

Mi objetivo es poder utilizar una entrada de base de datos específica como una constante. (Una vez insertado, la línea nunca cambiará en una instancia específica, pero los identificadores pueden ser diferentes en instancias diferentes).

Se me ocurrió una solución que podría aplicarse a este caso dependiendo de por qué está tratando de tener constantes dinámicas. Aquí hay un ejemplo en mi caso de uso, pero es bastante fácil reemplazar la definición de atributo por otra cosa.

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

Y así es como he comprobado:

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 
Cuestiones relacionadas