2009-10-11 17 views
6

que quieren manejar dos tipos de ajustes de configuración global:¿Cuál es la mejor manera de almacenar la configuración global de la aplicación en una aplicación de Rails?

  • Ajustes que pueden ser modificadas por el usuario, como si se envían o no correos de notificación de ciertos eventos.
  • Configuraciones que están vinculadas a una edición de producto específica, como la desactivación de una función en una versión gratuita, que solo está disponible en la versión comercial.

¿Cuál es la mejor manera de almacenar estas configuraciones? Base de datos, archivo de configuración, codificado en la fuente, ...?

Respuesta

6

Para ambos casos base de datos. Vas a utilizar las mismas estructuras para varias personas/productos, así que tiene sentido. También le permite cambiar cosas sin reiniciar el servidor.

Lo he manejado de esta manera en el pasado: Para configuraciones específicas para el usuario, he creado un modelo/tabla UserSettings, que tiene una relación uno a uno con un usuario. El razonamiento para esto es que la mayoría de mis operaciones que involucran usuarios no requieren que se carguen estas configuraciones, por lo que solo se incluyen en cargas de usuario de la base de datos cuando las necesito.

Cuando hago esto, por lo general, agruparé mis nombres de columna, de modo que pueda escribir ayudantes que creen dinámicamente en función de los nombres. Lo que significa que no tendré que modificar mis vistas para incorporar nuevas configuraciones a menos que agregue una con un esquema de nombres diferente.

Para la configuración específica de un producto, bueno, eso depende de cómo esté haciendo las cosas. Y hay un par de formas de interpretar tu pregunta.

La forma en que lo leo es que usted quiere decidir sobre un nivel de producto. Qué configuraciones los usuarios pueden anular o deshabilitar la configuración de un usuario. Y posiblemente defina algunas configuraciones específicas del producto.

Usaría un producto de uno a muchos para establecer la relación. La tabla de configuración sería algo simplista (product_id, setting_name, setting_default_value, allow_user_change)

Esto hace una serie de cosas. Le permite tener una lista variable de configuraciones para diferentes productos (perfecto para el caso en el que ofrece muchos productos diferentes en lugar de diferentes niveles de acceso a los servicios). También le permite definir qué configuraciones puede/no puede cambiar un usuario y dar valores para ese tipo de producto. Eso se puede cambiar desde una vista de administrador sin reiniciar la aplicación. Tampoco está vinculado a la configuración del usuario, hasta el punto de que si un usuario no tiene una configuración en la lista de productos, no habrá problemas.

Lo malo es que tendrá varias configuraciones comunes en esta tabla. Me gustaría mover la configuración de que cada producto tendrá un valor diferente a un campo en la tabla de productos.

También deberá escribir validaciones para asegurarse de que un usuario no cambie una configuración que su producto dice que no puede. También deberá escribir métodos de ayuda para fusionar las configuraciones del producto y del lado del usuario.

0

Aquí está mi experiencia con este tipo de cosas: no anula el comportamiento.

Usted ve, su primer pensamiento va a ser algo como esto:

Hmm .... Hay ajustes de todo el sistema que puede o no puede ser anulado por los usuarios (o productos). ¡Oye! ¡Yo se esto! ¡Es composición!

Y técnicamente, estaría en lo cierto. Entonces, creará una tabla de Configuraciones y pondrá toda su configuración allí. Y luego tendrá una tabla user_settings, donde anulará esas configuraciones si el usuario así lo decide. Y funcionará bien.

Hasta que agregue una configuración a una tabla y no a la otra.

O aparece un error que indica que la configuración X no se puede anular a nivel del usuario o del producto, y lleva más de 5 segundos determinar exactamente dónde se establece esa configuración.

Y entonces se dará cuenta de:

Hey, estoy hacer el seguimiento de todas estos ajustes en al menos dos lugares diferentes. Eso parece un poco tonto.

Y estarás en lo cierto.

Entonces, sí. Continúe y mantenga la configuración en el DB, pero guárdelos claramente para cada usuario o producto. Use valores predeterminados inteligentes en la creación de filas y mantendrá las cosas simples y agradables.

+1

Has hecho todo tipo de suposiciones sobre lo que está pensando y cómo va a implementar esto, pero su pregunta real fue "¿Cuál es la mejor manera de almacenar estas configuraciones?" Ninguna de sus suposiciones tiene sentido dentro de ese contexto. No creo que esto califique como un "hombre de paja", pero no estoy seguro de qué más llamarlo. –

0

Para el primer tipo de configuración, las mantendría en el modelo de Usuario (tabla de Usuarios).

El segundo tipo de configuración volvería a la base de datos. Por ejemplo, si un usuario tiene una cuenta gratuita, de alguna manera se guardará en la base de datos. Tendría algunos ayudantes en la aplicación, por ejemplo, "¿gratis?" o "comercial"? Estos ayudantes podrían averiguar si son verdaderos o falsos, preguntando al modelo de Usuario/Cuenta actualmente conectado. Luego puede usar estos ayudantes en diferentes partes de su aplicación para decidir si muestra u oculta cierta funcionalidad.

+0

Tendría que desnormalizarse para hacer esto. Probablemente en la forma de un campo de configuración serializada. No necesariamente es algo malo, pero la desnormalización siempre es una desventaja. –

1
class Flag < ActiveRecord::Base 
    # id, user_id, name, value (serialized probably) 

    belongs_to :user 

    DEFAULTS = { 
    "newsletter" => false 
    } 

    def self.lookup(user, flag) 
    # Please involve memcached here 
    case flag 
    when "ssl_enabled" 
     # Check if user has paid for sufficient access to SSL 
     return false 
    else 
     stored_flag = self.find_by_user_id_and_name(user.id, flag) 
     if stored_flag 
     return stored_flag.value 
     else 
     return DEFAULTS[flag] 
     end 
    end 
    end 
end 

class User < ActiveRecord::Base 
    has_many :flags 

    def flag(name) 
    return Flag.lookup(self, name) 
    end 
end 

Para la materia que se basa edición del producto, es probable que realmente no se puede almacenar cosas en la base de datos, porque la bandera va a estar basada en alguna pieza de código de autorización, en lugar de los datos estáticos.

Cuestiones relacionadas