#ruby-on-rails #devise #devise-invitable
#ruby-on-rails #разработка #разработка-invitable
Вопрос:
В моем приложении у меня есть пользователи и сайты (думайте об этом как о пользователях и организациях). Между ними находится таблица поиска, называемая SiteUser. В SiteUser:
belongs_to :site
belongs_to :user
before_validation :set_user_id, if: ->() { email != nil }
def set_user_id
existing_user = User.find_by(email: email)
self.user = if existing_user.present?
UserMailer.notify_existing_user(site, existing_user).deliver_now unless Rails.env.test?
existing_user
else
User.invite!(email: email)
end
end
Мне нужно, чтобы тема генерируемого электронного письма включала название сайта. «Примерная компания пригласила вас присоединиться к их сайту!»
И в теле электронного письма мне также нужно название сайта.
Я запутался в том, как перевести параметр сайта в devise invitable
. Как вы можете видеть в приведенном выше коде, если пользователь, которого приглашают на сайт, уже существует в нашей системе, я использую свою собственную почтовую программу, в которой я передаю site
и existing_user
, чтобы у меня был доступ к нему в моем представлении почтовой программы.
class UserMailer < ApplicationMailer
def notify_existing_user(site, user)
@site = site
@user = user
mail to: @user.email, subject: "You've been given access to #{@site.title} in the Dashboard."
end
end
Я не могу понять, как выполнить это аналогично с помощью программы devise invitable mailer, которая используется, когда пользователь еще не существует в системе.
Любая помощь, которую вы могли бы предоставить, была бы невероятно признательна!
Комментарии:
1. возможно, это не тот ответ, на который вы надеетесь, но предполагая, что существует какая-то логика «текущего сайта», вы могли бы сохранить «current_site_id» у вашего пользователя, а затем запросить его таким образом из вашей почтовой программы.
Ответ №1:
Способ, которым я добился этого, заключался в добавлении временного / виртуального атрибута для вызываемого пользователя invite_site_name
. Поскольку проблема заключалась в том, что site
это не было атрибутом User, поэтому я не мог отправить site
в User.invite!
.
class User < ActiveRecord::Base
attr_accessor :invite_site_name
и затем в моем CustomDeviseMailer
у меня был к нему доступ:
class CustomDeviseMailer < Devise::Mailer
helper :application # gives access to all helpers defined within `application_helper`.
include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`
default template_path: 'devise/mailer' # to make sure that your mailer uses the devise views
def invitation_instructions(record, token, opts={})
opts[:subject] = "#{record.invite_site_name} has invited you to their Dashboard! Instructions inside!"
super
end
end
Ответ №2:
Вы всегда можете переопределить метод subject_for в devise. Нашел это в выпуске gems, который также предлагает другой способ: https://github.com/scambra/devise_invitable/issues/660#issuecomment-277242853
Надеюсь, это поможет!
Комментарии:
1. Я смотрел на это, и это в основном имеет смысл для меня. Спасибо, что поделились этим. Я застрял на понимании того, как передать идентификатор сайта в метод, который я переопределяю (если я передам идентификатор стороны, я могу выполнить поиск и захватить объект сайта в почтовой программе).
User.invite!(email: email, site: site)
Приводит к `неизвестному атрибуту ‘site’ для пользователя. Потому что у пользователя есть множество сайтов. Но я просто хочу, чтобы этот идентификатор был передан через него, чтобы я мог запросить его в моем пользовательском почтовом устройстве.2. Попробуйте
self.site
, поскольку вы находитесь внутри SiteUser. Или задайте переменную в начале метода, например,invitation_site = self.site
а затем ссылайтесьinvitation_site
внутри вашегоinvite!
вызова.