2011-11-06 7 views
17

Tengo un campo tipo en un modelo llamado usuario que es un int en el db. El valor del int speficies es el tipo de tienda que es. Ejemplo:¿El mejor lugar para almacenar las constantes específicas del modelo en los rieles 3.1?

  • 0 = madre
  • 1 = padre
  • 2 = abuela
  • y así sucesivamente

Tengo varios otros campos como éste por lo que es una exageración para crear tablas de asociación .

En lugar de verificar los valores int sobre el lugar en los enunciados condicionales en el modelo y la lógica del controlador, ¿hay algún lugar en los raíles para almacenar estas constantes?

¿Para que pueda hacer esto con mis modelos y controladores?

if myuser.type == MOM 
elsif myuser.type == GRAND_MOTHER 

EDIT: Solución I fue con al final:

En el modelo:

# constants 
    TYPES = { 
    :mom => 0, 
    :dad => 1, 
    :grandmother => 2, 
    :grandfather => 3 
    } 

En la lógica:

if u.type == User::TYPES[:mom] 

pesar de que es más, me sentí es más intuitivo para otros desarrolladores cuando están leyendo mi código. Gracias a Taro a continuación por esta solución.

Respuesta

39

Algo así como:

class User < ActiveRecord::Base 

    TYPES = %w{ mom dad grandmother grandfather son } 

    TYPES.each_with_index do |meth, index| 
    define_method("#{meth}?") { type == index } 
    end 

end 


u = User.new 
u.type = 4 
u.mom? # => false 
u.son? # => true 
+0

Gran solución. ¿Hay alguna manera de usar los valores en la tarea? Algo así como ... 'u.type = MOM' ... de lo contrario, en caso de que un valor cambie con el tiempo, se requerirían modificaciones a ese valor en varios archivos. – Hopstream

+7

Coloque la constante dentro de la clase y consúltelo como 'User :: MOM'. – d11wtq

+0

¿Es posible usar esta misma notación para acceder al método en un modelo sin crear primero el objeto como en PHP? Aparece un error de "método indefinido" si hago algo como 'ModelName :: mydef()' – Hopstream

1

Una manera de ser escribir un archivo en la carpeta de inicializadores o carpeta lib

dicen app_contants.rb y en este archivo se puede escribir

MOM=1 

DAD=2 
  1. En caso de que escriba un inicializador yo u puede hacer

user.type == madre

2. Si se crea un archivo lib lo convierten en un módulo de

module app_constants 
    mom = 1 
    dad = 2 
    end 

y simplemente incluir este módulo donde quiera necesita

+0

dado que todas las constantes que quiero están relacionadas con los campos en los modelos, ¿sería una buena práctica incluir los módulos respectivos en sus modelos? Además, ¿esas constantes estarían entonces disponibles en cualquier controlador o archivo de rastreo que use esos modelos? – Hopstream

9

Desde Rails 4.1, no hay soporte para ActiveRecord::Enum.

Hay un tutorial útil here, pero en resumen:

# models/user.rb 
class User < ActiveRecord::Base 
    enum family_role: [ :mum, :dad, :grandmother] 
end 

# logic elsewhere 
u = User.first 
u.family_role = 'mum' 
u.mum? # => true 
u.family_role # => 'mum' 

Nota: Para convertir de su esquema actual (donde su base de datos ya almacena los números correspondientes a los valores), debe utilizar la sintaxis de hash:

enum family_role: { mum: 0, dad: 1, grandmother: 2 } 

Yo también propondría que reserve 0 para el estado predeterminado, pero eso es solo una convención y no crítico.

+1

Y sí, sé que esto no ayuda con su pregunta específica de Rails 3.1, pero espero que ayude a otros. –

+0

Agradable. +1 para pensar en futuros lectores – JGutierrezC

Cuestiones relacionadas