Ruby on Rails: Où pour définir des constantes globales?
Je suis juste de commencer avec mon premier Ruby on Rails webapp. J'ai un tas de différents modèles, vues, contrôleurs, et ainsi de suite.
Je suis désireux de trouver un bon endroit pour coller les définitions de vraiment constantes globales, qui s'appliquent à l'ensemble de mon ensemble de l'application. En particulier, ils s'appliquent à la fois dans la logique de mes modèles, et dans les décisions prises dans mes vues. Je ne peut pas trouver un endroit SEC pour mettre ces définitions où ils sont disponibles à la fois pour tous mes modèles et aussi dans tous mes points de vue.
Pour prendre un exemple concret, je veux une constante COLOURS = ['white', 'blue', 'black', 'red', 'green']
. Il est utilisé partout, dans les deux modèles et points de vue. Où puis-je définir en un seul lieu, de sorte qu'il est accessible?
Ce que j'ai essayé:
- Constante de la classe de variables dans le modèle.rb fichier qu'ils sont les plus associés avec, comme
@@COLOURS = [...]
. Mais je ne pouvais pas trouver une façon saine de le définir, de sorte que je peux écrire dans mon point de vueCard.COLOURS
plutôt que quelque chose encombrants commeCard.first.COLOURS
. - Une méthode sur le modèle, quelque chose comme
def colours ['white',...] end
- même problème. - Une méthode dans application_helper.rb - c'est ce que je fais jusqu'à présent, mais les aides ne sont accessibles que dans les vues, pas dans les modèles
- Je pense que je pourrais avoir essayé quelque chose dans l'application.rb ou de l'environnement.rb, mais ceux-ci ne sont pas vraiment l'air de droite (et ils ne semblent pas non plus)
Est-il pas possible de définir n'importe quoi pour être accessible à la fois des modèles et des points de vue? Je veux dire, je sais modèles et points de vue doivent être distincts, mais sûrement, dans certains domaines, il y aura des moments dont ils ont besoin pour se référer à un même domaine spécifique de la connaissance?
- double possible de Where/Comment le code des Constantes dans Rails 3
- Je comprends que c'est VRAIMENT la fin, mais pour les autres lecteurs, je me demande pourquoi vous n'avez pas il suffit de définir dans votre modèle et l'utilisation de vos contrôleurs de les faire passer votre point de vue. De cette façon, vous auriez un nettoyeur de séparation des préoccupations, plutôt que de créer des dépendances entre contrôleur/modèle ET de la vue/point de vue.
- Passer ces constantes dans chaque vue et d'assistance qui en a besoin? En d'autres termes, le contrôleur au courant de vues qui ont besoin de ce qui constantes? Cela ressemble plus à une violation de la MVC.
Vous devez vous connecter pour publier un commentaire.
Si votre modèle est vraiment "responsable" pour les constantes de s'en tenir là. Vous pouvez créer des méthodes de la classe pour y accéder sans la création d'une nouvelle instance de l'objet:
Alternativement, vous pouvez créer des variables de classe et un accesseur. Ce n'est cependant recommandé, en tant que variables de classe pourrait agir surprenant avec l'héritage et en multi-thread environnements.
Les deux options ci-dessus vous permettent de modifier le tableau retourné à chaque invocation de la méthode d'accesseur si nécessaire. Si vous avez un vrai vraiment immuable, constant, vous pouvez également définir dans la classe du modèle:
Vous pouvez également créer des constantes globales qui sont accessibles de partout dans un initialiseur comme dans l'exemple suivant. C'est probablement le meilleur endroit, si vos couleurs sont vraiment mondiale et utilisé dans plus d'un contexte de modèle.
Note: lorsqu'on définir des constantes ci-dessus, souvent, on veut
freeze
le tableau. Qui empêche les autres de code à partir plus tard (par inadvertance) la modification de la matrice, par exemple par l'ajout d'un nouvel élément. Une fois qu'un objet est gelé, il ne peut plus être modifié.config/initializers/my_constants.rb
route, n'oubliez pas de redémarrer le serveur:touch tmp/restart.txt
def self.colours
exemple n'est pas l'idéal. Chaque fois que vous appelezdef self.colours
, une nouvelle instance de la matrice sera retourné.#freeze
ne va pas aider dans ce cas. La meilleure pratique est de le déclarer comme un Rubis constante, dans ce cas, vous obtiendrez toujours le même objet.class Card; COLOURS = ['white', 'blue'].freeze; def self.colours; COLOURS; end; end
cela dit, l'allocation d'un tableau dans n'importe quelle langue peut être potentiellement problématique; pour l'un, c'est à l'aide de la mémoire pour aucune (bonne) raison. Si le chargement à partir d'une base, et que vous voulez mettre en cache la valeur, on peut aussi utiliser une variable d'instance de classe, qui peuvent être facilement chargées à l'aide de ladef self.colours
méthode. D'accord pour parler de l'immutabilité aspect bien.config/initializers/my_constants.rb
n'est pas accessible dans la vue des modèles, maisCard::COLOURS
est:uninitialized constant ActionView::CompiledTemplates::COLOURS
Certaines options:
À l'aide d'une constante:
Paresseux chargé à l'aide de variable d'instance de classe:
Si il est vraiment un constante globale (éviter les constantes globales de cette nature, bien que), vous pourriez également envisager de mettre
un haut niveau constant dans
config/initializers/my_constants.rb
par exemple.extend
le module dans la classe de sorte qu'il sera disponible avecCard.COLOURS
.extend
sa ne fonctionne pas pour moi. Lors de l'utilisation deinclude
je peux accéder comme:Card::COLOURS
/models
. C'est beaucoup mieux si vous créez un initialiseur./models
, mais seulement si son à l'intérieur d'un module, par exemplemodule Constants; COLOURS = ...; end
dans un fichier appelémodels/constants.rb
.~/lib/constants
Comme des Rails 4.2, vous pouvez utiliser le
config.x
propriété:Qui sera disponible en:
Une autre méthode de chargement de configuration personnalisé:
Dans les Rails Cinq & Six, vous pouvez utiliser le
configuration
objet directement pour une configuration personnalisée, en plus deconfig.x
. Toutefois, il ne peut être utilisé à des fins non-configuration imbriquée:Il sera disponible en:
Si une constante est nécessaire dans plus d'une classe, je l'ai mis dans le fichier config/initializers/contant.rb toujours en majuscules (liste des membres ci-dessous est tronqué).
Ils sont disponibles par le biais de l'application de l'exception dans le code du modèle en tant que tel:
Pour utiliser la constante dans le modèle, l'utilisation attr_accessor pour faire de la constante disponibles.
config/initializers/constants.rb
serait probablement un meilleur choix siPour l'ensemble de l'application des paramètres et des constantes globales je recommande d'utiliser Settingslogic. Ces paramètres sont stockés dans le fichier YML et peut être consulté à partir de modèles, vues et contrôleurs. Encore plus.. vous pouvez créer des paramètres différents pour tous vos environnements:
Quelque part dans la vue (je préfère les méthodes d'aide pour ce genre de choses) ou un modèle que vous pouvez obtenir, par ex., tableau de couleurs
Settings.colors.split(/\s/)
. Il est très flexible. Et vous n'avez pas besoin d'inventer un vélo.L'utilisation d'une méthode de classe:
Puis
Model.colours
sera de retour ce tableau. Sinon, créer un initialiseur et enveloppez-les constantes dans un module pour éviter les conflits d'espace de noms.Une autre option, si vous souhaitez définir votre constantes dans un seul endroit:
Mais encore de les rendre visibles à l'échelle mondiale, sans avoir à accéder pleinement qualifié de la sorte:
Un lieu commun de mettre application à l'échelle mondiale constantes est à l'intérieur de
config/application
.Essayez de garder tout constant à un seul endroit, Dans mon application, j'ai créé des constantes de dossier à l'intérieur d'initialiseurs comme suit:
et j'ai l'habitude de garder toutes constante dans ces fichiers.
Dans votre cas, vous pouvez créer un fichier sous constantes dossier que
colors_constant.rb
colors_constant.rb
N'oublie pas de redémarrer le serveur
Je ont généralement une "recherche" /modèle de table dans mon rails programme et l'utiliser pour les constantes. Il est très utile si les constantes sont va être différente pour différents environnements. En outre, si vous avez un plan, de les prolonger, de dire que vous voulez ajouter 'jaune' sur une date ultérieure, vous pouvez simplement ajouter une nouvelle ligne à la table de recherche et être fait avec elle.
Si vous donnez les autorisations d'administrateur pour modifier ce tableau, ils ne viendront pas à vous pour l'entretien. 🙂 SEC.
Ici est de savoir comment ma migration à quoi ressemble le code:
J'utilise des graines.rb pour pré-remplir.
La variable globale doit être déclarer dans
config/initializers
répertoireSelon votre condition, vous pouvez également définir certaines variables d'environnement, et aller le chercher via
ENV['some-var']
dans le code ruby, cette solution peut ne pas s'adapter pour vous, mais j'espère que ça peut aider les autres.Exemple: vous pouvez créer différents fichiers
.development_env
,.production_env
,.test_env
et de la charge en fonction de vos environnements d'application, cochez cette gen dotenv-rails qui permet d'automatiser cela pour votre.