2011-05-06 11 views
13

Estoy construyendo una aplicación Rails 3 para su implementación en Heroku, y me pregunto si hay alguna recomendación sobre cómo manejar multi-tenancy en mis modelos. Hace medio año, había una pregunta relacionada (#3776593) publicada aquí, pero no obtuvo muchas respuestas. También he visto Guy Naor's presentation on writing multi-tenant applications with Rails, pero parece que 2 de las 3 soluciones propuestas no funcionarían en Heroku. Tendría un enlace a estos, pero los nuevos usuarios de Stackoverflow están limitados a 2 hipervínculos.Escribiendo una aplicación Rails 3 de múltiples inquilinos para su implementación en Heroku

También he llegado a través de las siguientes herramientas:

Sólo me preguntaba si tiene experiencia, ya sea con la gema multiusuario o el simple carriles-multi- gema de arrendamiento Parece que la solución más sencilla sería la de simplemente poner un belongs_to en todos mis modelos que necesitan estar bajo una cuenta, pero que realmente me gustaría saber lo que está utilizando en el mundo real!

+1

Por curiosidad, ¿cómo terminaste resolviendo esto? – kmurph79

Respuesta

6

Los enfoques van desde "compartir nada", que generalmente significa una base de datos por inquilino, para "compartir todo", lo que generalmente significa que cada tabla contiene filas de muchos inquilinos. El espectro (a continuación) se puede desglosar por grado de aislamiento, por costo (costo por inquilino) y por facilidad de recuperación ante desastres.

  • Una base de datos por inquilino; costo más alto, mayor aislamiento, recuperación más fácil.
  • un esquema por el inquilino; costo entre los otros dos, buen aislamiento, recuperación bastante fácil, pero la recuperación generalmente degrada el rendimiento para otros inquilinos.
  • compartir las mesas entre los inquilinos; costo más bajo, aislamiento más bajo (tablas compartidas), recuperación de desastres difícil (la recuperación generalmente significa recuperar algunas filas para cada tabla). La recuperación generalmente degrada el rendimiento "mucho" para los otros inquilinos.

Todos estos son específicos de la plataforma en cierta medida. "Una base de datos por inquilino" tiene el mayor aislamiento cuando el dbms prohíbe que las consultas accedan a más de una base de datos. Pero algunas plataformas permiten consultas en múltiples bases de datos.

MSDN tiene un artículo decente que alcanza los puntos más importantes: Multi-Tenant Data Architecture.

Pero si estás limitado a Heroku, usted tiene que escoger una opción que apoya Heroku. No sé cuáles podrían ser esas opciones, pero sí sé que es mejor que no utilices SQLite en desarrollo. Las implementaciones de Heroku se ejecutarán en PostgreSQL; necesitas desarrollar contra PostgreSQL.

6

Como el autor de la gema multiusuario, obviamente soy parcial, ¡pero realmente creo que es una gran solución! El objetivo de la gema es simplificar esta necesidad de aplicación común y hacerla trivial de implementar.

La alternativa de la "vieja escuela" es utilizar el encadenamiento de objetos de carriles para garantizar que todas las consultas se realicen a través del elemento primario asociado. El problema con este enfoque es que su objeto Tenant se convierte en un vertedero para has_many associations.

class Tenant 
    has_many :users 
end 
# query for users in the current tenant 
current_tenant.users.find params[:id] 

La gema multiusuario resuelve esto asegurándose de que todas las consultas generadas automáticamente son conscientes de que el inquilino actual.Y también asegura que se creen registros nuevos y se asignen automáticamente al inquilino actual, por lo que no es necesario que agregue ninguna devolución de llamada previa a save_especial.

ejemplo:

Multitenant.with_tenant current_tenant do 
    # queries within this block are automatically 
    # scoped to the current tenant 
    User.all 

    # records created within this block are 
    # automatically assigned to the current tenant 
    User.create :name => 'Bob' 
end 
+3

Hola, Ryan, ¿por qué no tocaste el default_scope en lugar de usar el modo Multitentant.with_tenant? – rafamvc

2

estoy a punto de embarcarse en esta aventura (la implementación multiempresa para una pequeña aplicación rieles) y al mismo tiempo hacer la investigación me encontré con este SO puesto.

Es sorprendente que nadie haya mencionado el gran screencast de RyanB al implementar MT utilizando esquemas PostgreSQL que es compatible con Heroku.

Aquí está el enlace al screencast http://railscasts.com/episodes/389-multitenancy-with-postgresql.

Concepto:

En aplicación rieles, podemos establecer una ruta de búsqueda para la conexión pg

 connection.schema_search_path = "schema1, schema2, ..." 

cualesquiera acciones posteriores serán ejecutadas sobre SCHEMA1 si encuentra la tabla correspondiente allí. De lo contrario, busca la tabla en schema2 y así sucesivamente. Para estar con el esquema de toda la aplicación, incluido el inquilino será en público y la práctica habitual es hacer todas las tablas, excepto el inquilino vacío en el esquema público.

Registro nuevo inquilino:

Añadir una función after_create a su modelo inquilino para crear un nuevo esquema para el nuevo inquilino y crear todas las tablas (schema.rb carga) de aplicaciones (excepto inquilino) en este nuevo esquema.

usuario:

cuando un usuario visita, subdomain1.myapp.com, encontrar el esquema para este subdominio de la mesa inquilino y establecer la ruta de búsqueda de conexión a 'SCHEMA1, público' y autenticar al usuario.

Tenga en cuenta que mi intención es solo cubrir el concepto detrás de la solución. Consulte el screencast de RyanB para la solución real.

Cuestiones relacionadas