what variable define create ruby-on-rails constants global

ruby-on-rails - define - ruby variables



Ruby on Rails: ¿Dónde definir constantes globales? (12)

A partir de Rails 5.0, puede utilizar el objeto de configuration directamente para la configuración personalizada :

En config/application.rb (o config/custom.rb si lo prefiere)

config.colours = %w(white blue black red green)

Estará disponible como:

Rails.configuration.colours # => ["white", "blue", "black", "red", "green"]

Nota: Para la versión 4.2, necesita usar la propiedad config.x :

config.x.colours = %w(white blue black red green)

Que estará disponible como:

Rails.configuration.x.colours # => ["white", "blue", "black", "red", "green"]

Estoy empezando con mi primera aplicación web de Ruby on Rails. Tengo un montón de diferentes modelos, vistas, controladores y así sucesivamente.

Estoy deseando encontrar un buen lugar para pegar definiciones de constantes verdaderamente globales, que se apliquen a toda mi aplicación. En particular, se aplican tanto en la lógica de mis modelos como en las decisiones tomadas en mis puntos de vista. No puedo encontrar ningún lugar SECO para poner estas definiciones donde estén disponibles para todos mis modelos y también en todos mis puntos de vista.

Para tomar un ejemplo específico, quiero una constante COLOURS = [''white'', ''blue'', ''black'', ''red'', ''green''] . Esto se usa en todo el lugar, tanto en los modelos como en las vistas. ¿Dónde puedo definirlo en un solo lugar para que sea accesible?

Lo que he intentado:

  • Las variables de clase constantes en el archivo model.rb con las que están más asociadas, como @@COLOURS = [...] . Pero no pude encontrar una forma sensata de definirlo para poder escribir en mis puntos de vista Card.COLOURS lugar de algo torpe como Card.first.COLOURS .
  • Un método en el modelo, algo así como def colours [''white'',...] end - same problem.
  • Un método en application_helper.rb: esto es lo que estoy haciendo hasta ahora, pero los ayudantes solo son accesibles en vistas, no en modelos.
  • Creo que podría haber intentado algo en application.rb o environment.rb, pero eso realmente no parece correcto (y parece que tampoco funcionan)

¿No hay forma de definir algo para que sea accesible tanto desde los modelos como desde las vistas? Quiero decir, sé que los modelos y las vistas deben estar separados, pero seguramente, en algunos dominios, ¿habrá ocasiones en que deban referirse al mismo conocimiento específico del dominio?


Algunas opciones:

Usando una constante:

class Card COLOURS = [''white'', ''blue'', ''black'', ''red'', ''green'', ''yellow''].freeze end

Lazy cargado usando la variable de instancia de clase:

class Card def self.colours @colours ||= [''white'', ''blue'', ''black'', ''red'', ''green'', ''yellow''].freeze end end

Si es una constante verdaderamente global ( aunque evite las constantes globales de esta naturaleza ), también podría considerar poner una constante de nivel superior en config/initializers/my_constants.rb por ejemplo.


De acuerdo con su condición, también puede definir algunas variables ambientales y obtenerlas a través de ENV[''some-var''] en el código ruby, esta solución puede no ser adecuada para usted, pero espero que pueda ayudar a otros.

Ejemplo: puede crear diferentes archivos .development_env , .production_env , .test_env y cargarlos de acuerdo con sus entornos de aplicación, verifique este gen dotenv-rails que automatiza esto para su.


Intente mantener todo constante en un solo lugar. En mi aplicación, he creado una carpeta de constantes dentro de los inicializadores de la siguiente manera:

Y por lo general me mantengo todo constante en estos archivos.

En su caso, puede crear un archivo bajo la carpeta de constantes como colors_constant.rb

colors_constant.rb

No olvides reiniciar el servidor.


La variable global debe declararse en el directorio config/initializers

COLOURS = %w(white blue black red green)


Normalmente tengo una tabla / modelo de ''búsqueda'' en mi programa de rieles y la uso para las constantes. Es muy útil si las constantes van a ser diferentes para diferentes entornos. Además, si tiene un plan para extenderlos, digamos que desea agregar ''amarillo'' en una fecha posterior, simplemente podría agregar una nueva fila a la tabla de búsqueda y terminar con ella.

Si le otorga a la administración permisos para modificar esta tabla, no vendrán a usted para su mantenimiento. :) SECO.

Aquí es cómo se ve mi código de migración:

class CreateLookups < ActiveRecord::Migration def change create_table :lookups do |t| t.string :group_key t.string :lookup_key t.string :lookup_value t.timestamps end end end

Yo uso seeds.rb para pre-poblarlo.

Lookup.find_or_create_by_group_key_and_lookup_key_and_lookup_value!(group_key: ''development_COLORS'', lookup_key: ''color1'', lookup_value: ''red'');


Otra opción, si desea definir sus constantes en un solo lugar:

module DSL module Constants MY_CONSTANT = 1 end end

Pero aún así, hazlos visibles a nivel mundial sin tener que acceder a ellos de forma totalmente calificada:

DSL::Constants::MY_CONSTANT # => 1 MY_CONSTANT # => NameError: uninitialized constant MY_CONSTANT Object.instance_eval { include DSL::Constants } MY_CONSTANT # => 1


Para la configuración de toda la aplicación y para las constantes globales, recomiendo usar Settingslogic . Esta configuración se almacena en un archivo YML y se puede acceder desde modelos, vistas y controladores. Aún más ... puedes crear diferentes configuraciones para todos tus entornos:

# app/config/application.yml defaults: &defaults cool: saweet: nested settings neat_setting: 24 awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %> colors: "white blue black red green" development: <<: *defaults neat_setting: 800 test: <<: *defaults production: <<: *defaults

En algún lugar de la vista (prefiero los métodos de ayuda para este tipo de cosas) o en un modelo que puede obtener, por ejemplo, una gama de colores Settings.colors.split(//s/) . Es muy flexible. Y no necesitas inventar una bicicleta.


Si se necesita una constante en más de una clase, la puse en config / initializers / contant.rb siempre en mayúsculas (la lista de estados a continuación está truncada).

STATES = [''AK'', ''AL'', ... ''WI'', ''WV'', ''WY'']

Están disponibles en toda la aplicación, excepto en el código del modelo como tal:

<%= form.label :states, %> <%= form.select :states, STATES, {} %>

Para usar la constante en un modelo, use attr_accessor para hacer que la constante esté disponible.

class Customer < ActiveRecord::Base attr_accessor :STATES validates :state, inclusion: {in: STATES, message: "-- choose a State from the drop down list."} end


Si su modelo es realmente "responsable" de las constantes, debe pegarlas allí. Puede crear métodos de clase para acceder a ellos sin crear una nueva instancia de objeto:

class Card < ActiveRecord::Base def self.colours [''white'', ''blue''] end end # accessible like this Card.colours

Alternativamente, puede crear variables de clase y un descriptor de acceso. Sin embargo, esto no se recomienda, ya que las variables de clase pueden actuar como algo sorprendente con la herencia y en entornos de subprocesos múltiples.

class Card < ActiveRecord::Base @@colours = [''white'', ''blue''] cattr_reader :colours end # accessible the same as above

Las dos opciones anteriores le permiten cambiar la matriz devuelta en cada invocación del método de acceso, si es necesario. Si tiene una verdadera constante inmutable, también puede definirla en la clase modelo:

class Card < ActiveRecord::Base COLOURS = [''white'', ''blue''].freeze end # accessible as Card::COLOURS

También puede crear constantes globales a las que se pueda acceder desde cualquier lugar en un inicializador, como en el siguiente ejemplo. Este es probablemente el mejor lugar, si sus colores son realmente globales y se usan en más de un contexto modelo.

# put this into config/initializers/my_constants.rb COLOURS = [''white'', ''blue''].freeze

Nota: cuando definimos las constantes de arriba, a menudo queremos freeze la matriz. Eso evita que otro código se modifique más tarde (inadvertidamente) la matriz al agregar, por ejemplo, un nuevo elemento. Una vez que un objeto está congelado, ya no se puede cambiar.


Un lugar común para colocar constantes globales en toda la aplicación es dentro de config/application .

module MyApp FOO ||= ENV.fetch(''FOO'', nil) BAR ||= %w(one two three) class Application < Rails::Application config.foo_bar = :baz end end


Utilice un método de clase:

def self.colours [''white'', ''red'', ''black''] end

Entonces Model.colours devolverá esa matriz. Alternativamente, cree un inicializador y ajuste las constantes en un módulo para evitar conflictos de espacio de nombres.