Есть ли решение для Rails Gem Devise, чтобы позволить пользователю иметь несколько электронных писем?
Я ищу решение, позволяющее пользователю в моем приложении иметь более 1 электронной почты. Это должно работать подобно Facebook, LinkedIn и Quora. Если учетная запись может иметь несколько писем, 1 в качестве первичной.
Есть ли решение "под ключ" для разработки avaialble? Я надеюсь, что не придется писать это с нуля, учитывая, что это так распространено.
Идеи? Благодаря
Ответы
Ответ 1
Hm... Я предлагаю создать новую модель, вы сделаете что-то вроде этого:
Например, модель будет 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
Ответ 2
Ответ Боба близок, но у него есть потенциально опасная ошибка. Метод 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
важны, потому что Devise также использует этот метод для поиска User
на confirmation_token
, unlock_token
и reset_token
. Без ветки else любые вызовы этого метода, которые не имеют параметра email
, либо сбой, либо загрузка пользователя с помощью nil
email.
Ответ 3
Я бы предложил вам создать новую модель SecondaryEmail
.
A User
может has_many :secondary_emails
, и каждый SecondaryEmail
belongs_to :user
.
Вам нужно будет добавить проверку уникальности для каждого письма в SecondaryEmail
, и, кроме того, вам нужно будет убедиться, что новый SecondaryEmail уже не является основным электронным письмом любого пользователя.
Предоставьте интерфейс, чтобы User
мог добавлять свои вторичные_почты с этими проверками.
Следующий шаг будет переопределять SessionController
Devise.
При любой процедуре входа в систему настройте свою процедуру входа для SecondaryEmail.where(:email => params[:email])
всякий раз, когда электронное письмо не встречается в первичных электронных сообщениях пользователя. Если он существует, выполните аутентификацию с этим паролем пользователя, иначе пользователь не существует.
Это то, к чему я придумал. Мне бы очень хотелось узнать мнение экспертов и подход к этому.:)
Ответ 4
Я столкнулся с этой проблемой некоторое время назад - и изложил решение в моем блоге.
Ниже приведены шаги, описанные ниже:
- Информация электронной почты должна храниться в дополнительной модели, например
Email
. Таким образом, User
имеет множество связанных экземпляров Email
.
- Скорее всего, мы хотим назначить одно электронное письмо по умолчанию, которое мы можем использовать для связи с пользователем.
- Метод класса
User
class find_first_by_auth_conditions
используется для поиска пользователя для предоставленных учетных данных - поэтому нам придется переопределить этот метод для поиска с использованием модели Email
.
- Нам придется изменить представления по умолчанию, потому что они неявно предполагают наличие метода
Email
пользователя. Вместо того, чтобы полностью переписывать просмотры, мы можем использовать добавление прокси-доступа для электронной почты, который делегирует сообщение по умолчанию для пользователя.
- Если пользователю разрешено иметь несколько электронных писем, мы также хотели бы предоставить пользователю возможность добавлять/удалять электронные письма на странице редактирования учетной записи.
- Если вам нужна интеграция omniauth - тогда реализация запаса
User.from_omniauth
, изложенная в вики-разработке, должна быть изменена для поддержки нескольких электронных писем.
Моя реализация доступна в Github.
Ответ 5
Ответы, приведенные здесь, довольно хороши и должны решить вашу проблему. Чтобы ответить на ваш последний вопрос, я не думаю, что вы найдете камень для этого, так как он слишком прост, хотя и довольно распространен. Просто сделайте это с нуля, как было предложено, это не должно много работать:)
Ответ 6
Боб ответ забросил SQL-ошибку для меня в rails 4.1.5 - изменение ниже получило работу, за http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-eager-loaded-associations:
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
Ответ 7
Вы можете использовать драгоценный камень devise-multi_email: https://github.com/allenwq/devise-multi_email
Замените devise :authenticatable
на 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
И если вы хотите, чтобы все письма были подтверждены и восстановили пароль от любого из ваших писем, просто
devise :multi_email_authenticatable, :multi_email_confirmable, :confirmable