2012-07-18 11 views
6

Używam klejnotu acts_as_tenant do zarządzania wieloma dzierżawcami i używam go do zarządzania użytkownikami.Wyjątkowość użytkowników przy użyciu narzędzi i act_as_tenant w szynach 3

Mam tylko konfigurację zaprojektować model użytkownika i model konta dla lokatorów. Potrafię tworzyć użytkowników przeciwko wielu najemcom - wszystko działa dobrze, Z WYJĄTKIEM, gdy próbuję utworzyć dwóch użytkowników z tą samą wiadomością e-mail na podstawie różnych identyfikatorów dzierżawcy, otrzymuję błąd unikalności. Używam opcji validates_uniqueness_to_tenant zgodnie z opisem.

modelu User

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 

modelu Konto

class Account < ActiveRecord::Base 
    attr_accessible :name 
end 

Application Controller

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

To wygląda tak, jak powinno być oparte pracujących na całej dokumentacji w acts_as_tenant, muszę zastąpić zamiast tego coś na poziomie projektu?

EDYCJA: Po pewnym zarysowaniu głowy i odrobinie przerwy, problem polega na tym, że domyślnie program Devise dodał unikalny indeks do kolumny Email. To oczywiście nie żeluje z tym, co act_as_tenant chce zrobić ... Spróbuję usunąć indeks i sprawdzić, czy Devise pukes, czy nie.

EDYCJA 2: OK, oficjalnie już się na tym skończyłem. Mam ręczne uwierzytelnianie dla głównej strony i działa to poprawnie z acts_as_tenant. Mogę tylko założyć niekompatybilność pomiędzy acts_as_tenant i Devise na jakiejś warstwie - poza mną, aby ją znaleźć na tym etapie.

Odpowiedz

8

Jedynym sposobem, aby to zrobić poprzez usunięcie validatable moduł z opracowania i uruchamiać własne walidacje tak:

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

Dobra odpowiedź - warto zauważyć, że dla nikogo innego należy pamiętać o usunięciu unikalnego indeksu na pocztę e-mail, który również opracowuje. –

+0

FYI: AaT udostępnia sprawdzanie poprawności zakresu: 'validates_uniqueness_to_tenant: email'. Również format e-mail można łatwo zrobić za pomocą 'validates_format_of: email, z: Devise.email_regexp' – Besi

0

Nie testowałem tego, ale zastanawiam się, czy zmiana kolejności może pomóc act_as_tenant zrobić to, zanim program przejmie kontrolę.

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

przepraszam, nie działa. –

+0

Wygląda na to, że jesteś na coś z indeksem devise. Jeśli jest to jakakolwiek pomoc, w moich systemach pozwalam użytkownikom wiązać się z więcej niż jednym lokatorem, a następnie dać im możliwość zmiany obecnego najemcy. To może nie działać dla twoich szczególnych potrzeb. – ob1

0

Właśnie natknąłem się na to pytanie. Rozwiązanie Sweama jest całkiem dobre.

Ale wolę nie przesłonić domyślnego zachowania. Więc wpadłem na to rozwiązanie:

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 

Usuwamy błąd domyślnego sprawdzania poczty e-mail, dlatego ignorowanie sprawdzania oryginalności, a my znowu zrobić własną walidację. To, co dodałem, pochodzi z modułu Validatable, ale dodałem do niego :scope.

Ważne jest, aby zachować zamówienie. Dodaj powyższy kod po komendzie devise.

Powiązane problemy