2010-11-23 5 views
15

Je définir une constante dans un initialiseur dans Rails en utilisant la syntaxe suivante:définition constante dynamique dans Rails

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

Il fonctionne, si je commence une console et d'écrire

MyModule::MYCONSTANT 

Je reçois foobar comme prévu.

Le problème est que lorsque j'essaie de l'appeler dans un modèle, la constante n'est pas là.

Où D doit-il définir dynamiquement ma constante pour qu'elle soit également disponible dans mes modèles?

Si je le définit statiquement dans mon lib/mymodule.rb cela fonctionne mais je voudrais définir certaines constantes lors de l'exécution.

+0

Vous avez fait une faute de frappe: MY_CONSTANT vs MYCONSTANT. Est-ce juste une erreur dans la question, ou c'est le problème dans votre code? – Arsen7

+0

faute de frappe dans la question, merci! –

Répondre

3

Peut-être le chargement automatique est-il le problème en mode développement?

Votre classe de modèle est recréée pour chaque requête, vous devez donc créer la constante encore et encore.

Le problème disparaîtrait simplement en mode de production. Vous pouvez désactiver le chargement automatique en mode développement, mais cela vous forcera à redémarrer le serveur après chaque modification de votre code.

Voir config/environments/development.rb: config.cache_classes = false (remplacez true).

+0

parfait, c'était le problème. Merci :-) –

12

si vous voulez garder config.cache_classes = false, vous pouvez mettre

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

dans le bloc suivant application.rb:

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

J'ai trébuché sur ce que je voulais faire " constantes dynamiques ".

Mon but est de pouvoir utiliser une entrée de base de données spécifique en tant que constante. (Une fois insérée, la ligne ne changera jamais sur une instance spécifique mais les identifiants peuvent être différents sur des instances différentes).

Je suis venu avec une solution qui pourrait s'appliquer à ce cas en fonction de la raison pour laquelle vous essayez d'avoir des constantes dynamiques. Voici un exemple dans mon cas mais il est assez facile de remplacer la définition d'attribut par autre chose.

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

Et voici comment je l'ai testé:

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 
Questions connexes