2013-04-29 39 views
14

我正在尋找一種解決方案,以允許我的應用程序上的用戶擁有多個電子郵件。這應該與Facebook,LinkedIn和Quora類似。一個帳戶可以有多個電子郵件,其中1個爲主要電子郵件。Rails Gem Devise是否有解決方案以允許用戶擁有多個電子郵件?

是否有一個交鑰匙解決方案的設計avaialble?我希望不必從頭開始編寫它,因爲它很常見。

想法?由於

+0

是否要啓用登錄與二次郵件也是如此,對於任何用戶? – kiddorails 2013-04-29 17:50:57

+0

是的,用戶只能使用他們的任何電子郵件登錄。此外,電子郵件不應該能夠共存,整個系統中的每個帳戶都有唯一的電子郵件...就像Facebook如何處理這個... – AnApprentice 2013-04-29 17:51:34

+0

我不知道現有的解決方案,但如果您決定自己寫,你可以從這個開始,至少類似(多個可能的登錄值):https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in使用他們的用戶名或電子郵件地址 – MrTheWalrus 2013-04-29 18:05:07

回答

15

嗯......我會建議建立新的模式,你會做這樣的事情:

例如模型是UserEmail

class UserEmail < ActiveRecord::Base 
    belongs_to :user 
end 

class User < ActiveRecord::Base 
    has_many :user_emails 
end 

和覆蓋色器件的方法來查找記錄在User模型:

def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if email = conditions.delete(:email) 
    User.includes(:user_emails).where('user_emails.email = ?', email).first 
    else 
    super(warden_conditions) 
    end 

瞭解更多關於替代的位置:https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address

+0

+1即使我認爲完全相同的閱讀 – Viren 2013-05-06 06:58:25

+0

這將失敗(以一種潛在的不安全的方式)其他Devise查找,如通過他們的確認標記查找用戶或解鎖令牌。查看我的答案以解決問題。 – Brad 2013-05-15 20:42:00

+0

你如何處理密碼恢復?如果我想讓用戶選擇要將鏈接發送到哪個電子郵件,我該怎麼辦? – Gady 2013-05-16 14:22:23

4

我建議你創建一個新的模型SecondaryEmail
A User可以has_many :secondary_emails,並且每個SecondaryEmailbelongs_to :user

您必須爲SecondaryEmail中的每封電子郵件添加驗證唯一性,此外還必須確保沒有新的SecondaryEmail已經是任何用戶的主要電子郵件。
提供接口,以便User可以添加他的secondary_emails以及這些驗證。

下一步將覆蓋SessionController設計
在任何登錄過程中,只要在用戶的主電子郵件中找不到電子郵件,就設置登錄過程SecondaryEmail.where(:email => params[:email])。如果存在,則使用該用戶的密碼進行身份驗證,否則,用戶不存在。

這就是我到目前爲止所提出的。我真的很想知道專家的觀點和方法。 :)

1

這裏給出的答案很不錯,應該可以解決你的問題。要回答你最後的問題,我認爲你不會爲此找到寶石,因爲它太簡單了,即使它很常見。只要按照建議從頭開始,它應該不會太多工作:)

8

鮑勃的答案是接近,但它有一個潛在的危險的錯誤。該find_first_by_auth_conditions方法應該是這樣的:

def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if email = conditions.delete(:email) 
    User.includes(:user_emails).where('user_emails.email = ?', email).first 
    else 
    super(warden_conditions) 
    end 
end 

電子郵件檢查,並打電話給super是很重要的,因爲設計也使用了這種方法,通過confirmation_tokenunlock_token,並reset_token查找User秒。沒有else分支,任何對此方法沒有email參數的調用都將失敗,或者使用nil電子郵件加載用戶。

+2

謝謝)更新我的回答) – Bob 2013-05-16 07:35:31

3

我前面遇到過這個問題 - 並在my blog中概述瞭解決方案。

的步驟總結如下:

  • 電子郵件信息必須存儲在一個額外的模型,說Email。所以User有許多相關的Email實例。
  • 我們很可能希望指定一封電子郵件作爲默認電子郵件,我們可以使用這封電子郵件與用戶進行溝通。
  • Userfind_first_by_auth_conditions的類方法用於查找用戶提供的憑據 - 因此我們將不得不覆蓋該方法以使用Email模型進行搜索。
  • 我們將不得不更改默認視圖,因爲它們隱含假定存在email方法的用戶。我們可以使用添加一個代理訪問器來代替用戶的默認電子郵件,而不是完全重寫視圖。
  • 如果允許用戶有多個電子郵件 - 我們還希望提供用戶工具來在帳戶編輯頁面中添加/刪除電子郵件。
  • 如果您需要omniauth集成 - 那麼devise wiki中概述的股票實現User.from_omniauth將不得不修改以支持多個電子郵件。

我的實施可用on Github

0

您可以使用色器件,multi_email寶石:https://github.com/allenwq/devise-multi_email

更換​​與devise :multi_email_authenticatable,讓您的型號可能是這樣的:

class User < ActiveRecord::Base 
    has_many :emails 

    # Replace :database_authenticatable, with :multi_email_authenticatable 
    devise :multi_email_authenticatable, :registerable 
end 

class Email < ActiveRecord::Base 
    belongs_to :user 
end 

如果你想共同所有的電子郵件nfirmable,並從你的電子郵件的人找回密碼,只需

devise :multi_email_authenticatable, :multi_email_confirmable, :confirmable

相關問題