2008-12-11 8 views
21

J'ai certaines données que je veux stocker quelque part dans mon application Rails parce que je l'utilise pour générer des champs de formulaire, vérifier un formulaire soumis pour s'assurer que ses valeurs sont valides, etc. Fondamentalement, je veux les données un endroit parce que je m'en sers à plusieurs endroits.valeurs constantes dans Rails

Auparavant, je définissais une méthode initialize dans mon contrôleur et initialisais les variables d'instance dans cette méthode, par ex. @graph_types = ['bar', 'line']. Cela semblait une mauvaise idée parce que c'est vraiment initialize qui était utilisé pour (initialiser ces valeurs) et les variables d'instance pourraient être changées plus tard, ce que je ne veux pas. Maintenant, je définis des constantes en dehors de n'importe quelle méthode dans mon contrôleur, juste en haut après mes filtres, et je les gèle, par exemple. GraphTypes = ['bar', 'line'].freeze. Je ne voulais pas stocker de telles données dans un fichier de configuration parce que je devais alors garder la trace d'un fichier supplémentaire, lire le fichier et l'analyser, etc. Je ne voulais pas stocker ces données dans la base de données parce que cela semble être trop lourd; Je n'ai pas besoin de faire des requêtes folles LEFT OUTER JOIN-type combinant les types de graphiques disponibles avec une autre de mes constantes, disons Themes = ['Keynote', 'Odeo', '37 Signals', 'Rails Keynote'].freeze. Je ne voulais pas stocker les données dans environment.rb car ces données ne concernent qu'un contrôleur particulier. Compte tenu de tout cela, est-ce que je vais à propos de cette «façon Ruby»?

Répondre

9

Je crois que ce que vous faites actuellement est bien; Vous avez dit que les données ne concernent qu'un seul contrôleur, et que c'est à ce niveau qu'il appartient. Si cela était nécessaire pour plusieurs contrôleurs, ou s'ils étaient plus complexes que des valeurs constantes, d'autres approches peuvent avoir du sens.

4

Oui, ce que vous faites est bien. Il est plus idiomatique Ruby d'appeler votre constante GRAPH_TYPES cependant. Incidemment, j'éviterais de définir initialize dans vos contrôleurs. On dirait que cela pourrait conduire à des problèmes.

1

Si vous générez des formulaires liés à une ressource, il sera intéressant de le stocker dans les modèles. Vous n'avez pas besoin de le stocker dans la base de données car il peut s'agir de simples variables/méthodes de classe ou d'instance.

La même idée est pour la validation. Si vous validez des ressources/instances de modèle, il sera alors judicieux de stocker les paramètres de validation dans la classe du modèle.

De toute façon, il sera beaucoup plus proche du modèle 'modèle épais et contrôleur mince' que l'une des variantes que vous avez mentionnées.

27

Pour les constantes qui n'appartiennent vraiment nulle part ailleurs, j'ai une classe StaticData.

class StaticData 

    GRAPH_TYPES = ['bar', 'line'] 

    SOMETHING_ELSE = ['A', 'B'] 

    end 

Puis-je obtenir à avec

StaticData::GRAPH_TYPES 
+2

Où placez-vous la classe? Le situez-vous avec vos modèles? – ahsteele

+3

Eh bien, je le mets dans le répertoire models, mais il vaudrait probablement mieux le mettre en lib. – user37011

3

Je suis d'accord avec ce que certains IDBD et paradisepete. L'utilisation de constantes dans le modèle serait le meilleur moyen de faire en sorte que le contrôleur soit maigre et le modèle gros. Voir Rails view tips Par exemple si vous aviez un contrôleur de métriques lié à un modèle métrique.Dans le modèle métrique classe métrique < ActiveRecord :: Base GRAPHTYPES = [ 'bar', 'ligne']

Puis dans la vue que vous pourriez faire quelque chose comme

f.select: graph_type, métrique :: GRAPHTYPES

11

La même réponse I wrote previously to a similar question s'applique et affiche comme cette réponse apparaît toujours dans les résultats de recherche.

Mettre une constante dans le contrôleur a du sens car la constante s'y rapporte directement. Les constantes doivent être placées dans le fichier d'initialisation dédié: Rails.root/config/initializers/constants.rb.

Comme par le commentaire figurant dans application.rb:

# Application configuration should go into files in config/initializers 
# -- all .rb files in that directory are automatically loaded 

This is still valid as of Rails 3.

+1

Sasha, quelle portée utilisez-vous pour définir les constnns dans votre fichier 'config/initializers/constants.rb'? Mettez-vous juste 'MAGIC_NUMBER = 42' dans la portée globale, enveloppez-le dans un bloc' module YourApp', ou autre chose? – evanrmurphy

+1

@evanrmurphy c'est à vous de décider. L'enveloppement de vos constantes dans un espace de noms est le plus sûr pour éviter les conflits de noms et ajoute également un contexte supplémentaire lors de l'utilisation des constantes, mais certaines personnes préfèrent ne pas utiliser d'espace de noms (portée globale). – Dennis

Questions connexes