2012-07-18 19 views
6

Estoy usando la gema acts_as_tenant para administrar multi-tenancy, y estoy usando un dispositivo para administrar usuarios.Unicidad de usuarios con idear y actuadores_as_teniente en rieles 3

Solo tengo la configuración de diseño Modelo de usuario y Modelo de cuenta para inquilinos. Puedo crear usuarios contra varios inquilinos; todo funciona bien. EXCEPTO cuando intento crear dos usuarios con el mismo correo electrónico contra ID de inquilino diferente, obtengo un error de uniformidad. Estoy usando la opción validates_uniqueness_to_tenant como se describe.

modelo de usuario

class User < ActiveRecord::Base 
    # Include default devise modules. Others available are: 
    # :token_authenticatable, :confirmable, 
    # :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    attr_accessible :email, :password, :password_confirmation, :remember_me 

    acts_as_tenant(:account) 
    validates_uniqueness_to_tenant :email 
end 

modelo cuenta

class Account < ActiveRecord::Base 
    attr_accessible :name 
end 

Controlador de aplicación

class ApplicationController < ActionController::Base 
    set_current_tenant_by_subdomain(:account, :subdomain) 
    protect_from_forgery 
end 

Esta parece que debería estar trabajando basa en toda la documentación en acts_as_tenant, necesito para invalidar algo en el nivel del ingenio en su lugar?

EDITAR: Después de algunos arañazos en la cabeza y un poco de descanso, el problema es que creo que, por defecto, Devise ha agregado un índice único a la columna Correo electrónico. Esto, obviamente, no se corresponde con lo que actúa_como_gente quiere hacer ... Voy a tratar de eliminar el índice y ver si el programa vomita o no.

EDIT 2: Bien, oficialmente me he rendido de esto por ahora. Tengo una autenticación automática para el sitio principal y esto funciona correctamente con acts_as_tenant. Solo puedo suponer cierta incompatibilidad entre acts_as_tenant y Devise en alguna capa, más allá de mí para encontrarla en este momento.

Respuesta

8

La única manera de hacer esto es mediante la eliminación del módulo validable de idear y ejecutar sus propias validaciones de este modo:

class User < ActiveRecord::Base 
    acts_as_tenant :account 
    attr_accessible :email, :password, :remember_me 

    #remove :validatable 
    devise :database_authenticatable, :registerable, 
    :recoverable, :rememberable, :trackable 

    #run own validations 
    #I've omitted any emailformatting checks for clarity's sake. 
    validates :email, 
    presence: true, 
    uniqueness: { scope: :account_id, case_sensitive: false } 
    validates :password, 
    presence: true, 
    length: { :in => 6..20 }, 
    :if => :password_required? 

protected 
    # copied from validatable module 
    def password_required? 
    !persisted? || !password.nil? || !password_confirmation.nil? 
    end 

end 
+3

Buena respuesta: vale la pena señalar para cualquier otra persona que recuerde eliminar el índice único en el correo electrónico que también crea adiciones. –

+0

FYI: AaT proporciona un validador de ámbito: 'validates_uniqueness_to_tenant: email'. También el formato de correo electrónico se puede hacer fácilmente usando 'validates_format_of: email, con: Devise.email_regexp' – Besi

0

No lo he probado, pero me pregunto si cambiar el orden podría ayudar a acts_as_tenant a hacer su trabajo antes de que el diseño tome el control.

class User < ActiveRecord::Base 

    acts_as_tenant(:account) 
    validates_uniqueness_to_tenant :email 

    # Include default devise modules. Others available are: 
    # :token_authenticatable, :confirmable, 
    # :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
    :recoverable, :rememberable, :trackable, :validatable 

    attr_accessible :email, :password, :password_confirmation, :remember_me 

end 
+0

no lo siento, no funciona. –

+0

Parece que estás en algo con el índice de diseño. Si sirve de algo, en mis sistemas les permito a los usuarios enlazar a más de un inquilino y luego les da la posibilidad de cambiar su inquilino actual. Esto puede no funcionar para sus necesidades particulares. – ob1

0

encontré con esta pregunta. La solución de Sweam es bastante buena.

Pero prefiero no anular el comportamiento predeterminado. Así me ocurrió con esta solución:

validate :remove_old_email_validation_error 
validates_uniqueness_of :email, :allow_blank => true, :if => :email_changed?, :scope => [:account_id] 

private 

def remove_old_email_validation_error 
    errors.delete(:email) 
end 

eliminamos el error de validación por defecto para el correo electrónico, por lo tanto, haciendo caso omiso de la comprobación de validación, y lo hacemos nuestra propia validación de nuevo. Lo que he agregado es del módulo Validatable, pero he agregado :scope a él.

Es importante mantener el orden. Agregue el código anterior después del comando devise.

Cuestiones relacionadas