2008-12-11 8 views
21

Tengo algunos datos que quiero almacenar en algún lugar de mi aplicación Rails porque los utilizo para generar campos de formulario, verificar un formulario enviado para garantizar que sus valores sean válidos, etc. Básicamente, quiero los datos en un lugar porque lo uso en varios lugares.valores constantes en Rails

Anteriormente, estaba definiendo un método initialize en mi controlador e inicializando variables de instancia dentro de ese método, p. Ej. @graph_types = ['bar', 'line']. Esto parecía una mala idea porque en realidad se usaba todo (initialize) para (inicializar esos valores) y las variables de instancia podrían cambiarse más tarde, lo que no quiero.

Ahora, defino constantes fuera de cualquier método en mi controlador, en la parte superior después de mis filtros, y los congelo, p. GraphTypes = ['bar', 'line'].freeze.

No quería almacenar tales datos en un archivo de configuración porque entonces tendría que hacer un seguimiento de un archivo adicional, leer en el archivo y analizarlo, etc. No quería almacenar esta información en la base de datos porque eso parece exagerado; No necesito hacer ninguna loca búsqueda de tipo LEFT OUTER JOIN que combine tipos de gráficos disponibles con otra de mis constantes, digamos Themes = ['Keynote', 'Odeo', '37 Signals', 'Rails Keynote'].freeze. No quería almacenar los datos en environment.rb porque estos datos solo se refieren a un controlador en particular.

Teniendo en cuenta todo esto, ¿estoy hablando de este "camino de Ruby"?

Respuesta

9

Creo que lo que está haciendo actualmente está bien; dijiste que los datos solo se refieren a un controlador y, por lo tanto, ahí es donde pertenece. Si fuera necesario para múltiples controladores, o si fueran más complejos que los valores constantes, otros enfoques pueden tener sentido.

4

Sí, lo que estás haciendo está bien. Es más idiomático que Ruby llamar a tu constante GRAPH_TYPES.

Por cierto, evitaría definir initialize en sus controladores. Parece que podría ocasionar problemas.

1

Si está generando formularios que están relacionados con algún recurso, será una buena variante almacenarlo en los modelos. No necesita almacenarlo en DB porque puede ser una clase simple o variables/métodos de instancia.

La misma idea es para la validación. Si está validando instancias de recursos/modelo, será una elección razonable almacenar los parámetros de validación dentro de la clase de modelo.

De todos modos, estará mucho más cerca del patrón "modelo grueso y controlador delgado" que cualquiera de las variantes que mencionó.

27

Para las constantes que realmente no pertenecen a ningún otro lado, tengo una clase StaticData.

class StaticData 

    GRAPH_TYPES = ['bar', 'line'] 

    SOMETHING_ELSE = ['A', 'B'] 

    end 

en cuando me siento en ella con

StaticData::GRAPH_TYPES 
+2

¿Dónde poner la clase? ¿Lo localizas con tus modelos? – ahsteele

+3

Bueno, lo pongo en el directorio de modelos, pero probablemente sería mejor ponerlo en lib. – user37011

3

estoy de acuerdo con lo que algunos IDBD y paradisepete. Usar constantes en el modelo sería la mejor manera de hacerlo para que el controlador sea delgado y el modelo gordo. vea Rails view tips Por ejemplo, si tenía un controlador de métricas vinculado a un modelo de métrica.En el modelo métrico clase Métricas < ActiveRecord :: Base GRAPHTYPES = [ 'bar', 'línea']

Luego, en la vista que se podría hacer algo como

f.select: graph_type, Métricas :: GRAPHTYPES

11

La misma respuesta I wrote previously to a similar question se aplica y se publica ya que esta respuesta aún aparece en los resultados de búsqueda.

Poner una constante en el controlador tiene sentido ya que la constante pertenece directamente a él. Las constantes deberían colocarse en el archivo de inicializador dedicado: Rails.root/config/initializers/constants.rb.

De acuerdo con el comentario que aparece en 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, ¿qué ámbito usas para definir constatns en tu archivo 'config/initializers/constants.rb'? ¿Pone 'MAGIC_NUMBER = 42' justo en el alcance global, lo ajusta en un bloque' module YourApp', o algo más? – evanrmurphy

+1

@evanrmurphy que depende de usted. Envolver sus constantes en un espacio de nombres es lo más seguro para evitar conflictos de nombres y también agrega un contexto extra al usar las constantes, pero algunas personas prefieren no tener espacios de nombres (es decir, alcance global). – Dennis