2014-02-26 4 views
11

zwischen drei Modellen aufgeteilt Sagen wir, ich habe folgendes in einer Rails-4 App:Wie die Devise Juwel in einer Rails-Anwendung verwenden, wo die „User“ ist

class Person < ActiveRecord::Base 
    has_many :email_addresses, as: :emailable 
    has_one :user_account 
end 

class EmailAddress < ActiveRecord::Base 
    belongs_to :emailable, polymorphic: true 
    # There is an :address column 
end 

class UserAccount < ActiveRecord::Base 
    belongs_to :person 
end 

Eine Person, mehrere E-Mail-Adressen haben kann. Eine Person kann auch ein Benutzerkonto haben. (Ich habe dies in sein eigenes Modell verschoben, da nicht alle Personen Benutzer sein würden.) Jede der E-Mail-Adressen der Person könnte als "Benutzername" beim Einloggen verwendet werden.

Angesichts dieser würde ich gerne die verwenden Juwel entwickeln. Ich sehe, dass Sie das Modell angeben können, auf das die Authentifizierung angewendet wird. User ist weit verbreitet, aber ich würde UserAccount verwenden. Devise erwartet jedoch, dass das E-Mail-Feld (Benutzername) in diesem Modell enthalten ist.

Wenn eine Person ein Benutzerkonto registriert, würden tatsächlich drei verknüpfte Datensätze erstellt (Person, EmailAddress und UserAccount). Ich kann nicht herausfinden, wie man Devise dazu bringt, mit diesem Setup zu arbeiten. Irgendwelche Ideen? Danke für jede Hilfe.

Antwort

4

Eine Option wäre, die E-Mail-Methode von Ihrem UserAccount an Ihrem E-Mail-Modell zu delegieren und den Finder def self.find_first_by_auth_conditions(warden_conditions) durch die devise Anmeldeprozedur verwendet, außer Kraft setzen. Ich fand eine ziemlich nette blog post, die dies in der Tiefe beschreibt und eine andere stackoverflow answer, die den gleichen Ansatz hat. Es gibt auch a section in the docs darüber, wie man ein Gerätekonto mit mehreren E-Mails bestätigt.

Da Ihre Einrichtung ein wenig komplizierter ist, könnten Sie auch EmailAddress als primäres Geräte-Modell verwenden und die Passwort-Methoden an die UserAccount delegieren.
Dies wäre möglicherweise nützlich, wenn Sie jede E-Mail-Adresse mit bestätigbaren und nicht nur das Benutzerkonto bestätigen müssen. Dieses Setup würde diesen Finder außer Kraft setzen, aber Sie könnten andere Probleme mit dem delegierten Passwort bekommen, wie es noch nie zuvor versucht wurde.

1

Wenn Sie Active verwenden,

Zuerst fügen

attr_accessor :email 

zu user_account (ich denke, das ist der einfachste Weg mit devise Form zu behandeln)

Als nächstes müssen Sie ändern Anmeldeverfahren entwickeln. Noch in Ihrem user_account, überschreiben die devise Methode,

def self.find_for_database_authentication(warden_conditions) 
    conditions = warden_conditions.dup 
    if email = conditions.delete(:email) 
     where(conditions.to_h).includes(:email_addresses).where(email_addresses: {email: email}).first 
    else 
     where(conditions.to_h).first 
    end 
    end 

Sie auch über

class UserAccount < ActiveRecord::Base 
    belongs_to :person 
    has_many :email_addresses, through: :person 

den Code arbeiten folgende definieren müssen möglicherweise zu bekommen, die einfach funktionieren sollte, habe ich dies mit aktiven Datensatz getestet aber wenn Sie Mongoid verwenden, wird die Lösung wahrscheinlich anders sein.

Beachten Sie, dass ich den Code aus der How To: Allow users to sign in using their username or email address Dokumentation des Geräts geändert habe, um die Lösung zu erhalten.

Verwandte Themen