更改了Devise邮件程序模板路径,现在Devise Invitable的电子邮件主题行失败

Jos*_*vak 6 ruby-on-rails devise devise-invitable

我创建了一个自定义设计邮件程序来更改视图中Devise电子邮件模板的位置.我做了以下更改:

#/config/initializers/devise
config.mailer = 'CustomDeviseMailer'
Run Code Online (Sandbox Code Playgroud)

# app/mailers/customer_devise_mailer.rb
    def headers_for(action, opts)
        headers = {
            :subject       => translate(devise_mapping, action),
            :from          => mailer_sender(devise_mapping),
            :to            => resource.email,
            :template_path => '/mailers/devise'
        }.merge(opts)
    end
Run Code Online (Sandbox Code Playgroud)

现在我的电子邮件模板位于:/ app/views/mailers/devise /

问题是当一个Devise Invitable .invite!发出呼叫,电子邮件的主题行说明错误:" translation missing: en.#<Devise::Mapping:0x007fe8fb6f4578>".

我怀疑我需要对/config/locales/devise_invitable.en.yml文件进行调整.我也用/app/controllers/invitations_controller.rb.覆盖了Devise Invitable控制器.

我应该对devise_invitable.en.yml文件做什么补充?谢谢.

Jos*_*vak 7

我实现的解决方案是禁用默认的Devise Invitable邮件程序,而是使用我自己的邮件程序.该解决方案类似于Devise Invitable Wiki上的"允许用户创建自定义邀请消息"指南中的解决方案.

我做了以下更改.

将配置更改为自定义邮件程序:

# config/initializers/devise
config.mailer = 'CustomDeviseMailer'
Run Code Online (Sandbox Code Playgroud)

在自定义邮件程序中指定新的Devise电子邮件模板路径(并将Devise电子邮件模板移动到此文件夹):

# app/mailers/customer_devise_mailer.rb
def headers_for(action, opts)
    super.merge!({template_path: '/mailers/devise'}) # this moves the Devise template path from /views/devise/mailer to /views/mailer/devise
end
Run Code Online (Sandbox Code Playgroud)

使用该命令生成邮件程序以处理被覆盖的Devise Invitable电子邮件rails generate mailer InvitableMailer.

覆盖Devise Invitable控制器上的create操作.您需要的代码将类似于以下内容.我遗漏了我的respond_to块,因为它是为我的应用程序定制的.

# controllers/invitations_controller.rb
class InvitationsController < Devise::InvitationsController

    # POST /resource/invitation
    def create
        @invited_user = User.invite!(invite_params, current_inviter) do |u|
            # Skip sending the default Devise Invitable e-mail
            u.skip_invitation = true
        end

        # Set the value for :invitation_sent_at because we skip calling the Devise Invitable method deliver_invitation which normally sets this value
        @invited_user.update_attribute :invitation_sent_at, Time.now.utc unless @invited_user.invitation_sent_at
        # Use our own mailer to send the invitation e-mail
        InvitableMailer.invite_email(@invited_user, current_user).deliver

        respond_to do |format|
            # your own logic here. See the default code in the Devise Invitable controller.
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

邀请控制器现在调用我们生成的邮件程序而不是默认邮件程序.在我们的邮件程序中添加一个方法来发送电子邮件.

# app/mailers/invitable_mailer.rb
class InvitableMailer < ActionMailer::Base
    default from: "blah@blah.com"

    def invite_email(invited_user, current_invitor)
        @invited_user = invited_user
    @current_invitor = current_invitor

        # NOTE: In newever versions of Devise the token variable is :raw_invitation_token instead of :invitation_token
        # I am using Devise 3.0.1
        @token = @invited_user.invitation_token
        @invitation_link = accept_user_invitation_url(:invitation_token => @token)

        mail(to: @invited_user.email,
            from: "blah@blah.com",
            subject: "Invitation to SERVICE",
            template_path: "/mailers/devise")
    end
end
Run Code Online (Sandbox Code Playgroud)

我的自定义邀请电子邮件的模板是app/views/mailers/devise/invite_email.html.erb.在该电子邮件中,我使用以下代码链接到接受邀请URL以及邀请令牌<%= link_to 'Accept invitation', @invitation_link %>

此外,我添加attr_accessible :invitation_sent_at到我的用户模型,以便我可以:invitation_sent_at attribute从邀请控制器更新.

我希望这有帮助.