Rails 使用 ActionMailer 退订 link

Rails unsubscribe link with ActionMailer

我有一个电子邮件模型供用户注册,以便在添加或更新文章时接收电子邮件通知。电子邮件正常工作,但我收到一条错误消息,其中包含我在 email.rb 文件中生成的取消订阅方法。我在 2012 年发布的另一个 Whosebug 问题中找到了取消订阅解决方案,但我没有看到如何正确使用该解决方案。

电子邮件模型:

    class Email < ActiveRecord::Base
      validates :email, uniqueness: true
      validates :email, presence: true

      def unsubscribe
        Email.find(params[:id]).update_attributes(permissions: false)
      end
    end

文章模型:

    class Article < ActiveRecord::Base
      ...
      has_many :emails

      after_create :send_new_notifications!
      after_update :send_update_notifications!

       def send_update_notifications!
        email = Email.where(permissions: true)
        email.each do |email|
           UpdatedArticleMailer.updated_article(email, self).deliver_later
         end
       end

      def send_new_notifications!
        email = Email.where(permissions: true)
        email.each do |email|
          ArticleNotificationMailer.new_article(email, self).deliver_later
        end
      end
    end

取消订阅 link 在更新的文章电子邮件中:

        <%= link_to "Unsubscribe", email_url(@email.unsubscribe) %>

错误信息:

undefined local variable or method `params' for #<Email:0x007ff5c2955e88>
  def unsubscribe
   Email.find(params[:id]).update_attributes(permissions: false)
  end
 end

params[:id] 仅在控制器中可用。

你的 link_to 也没有意义,看起来你正在尝试路由到你的模型,那些是不可路由的。它应该是 link 到控制器操作,例如 EmailsController#Unsubscribe 并且 URL 将需要某种 ID。

class EmailsController < ApplicationController
  def unsubscribe
    if email = Email.find(params[:id])
      email.update_attribute(permissions: false)
      render text: "You have been unsubscribed"
    else
      render text: "Invalid Link"
    end
  end
end

这没有考虑到您可能想要使用令牌而不是 ID,在这种情况下,请参阅本文以了解如何使用 MessageVerifier。

http://ngauthier.com/2013/01/rails-unsubscribe-with-active-support-message-verifier.html

您不能从模型中调用参数。但此外,您在生成视图时调用了取消订阅函数,我认为这不是我们的意图。您的设置应该是:

config/routes.rb

resources :emails do
  get :unsubscribe, on: :member
end

这会为您提供正确的点击路径。

app/controllers/email_controller.rb

def unsubscribe
  email = Email.find params[:id]
  email.update_attributes(permissions: false)
  ... { handle errors, redirect on success, etc } ...
end

这处理控制流。

在视图中,link 变为:

unsubscribe_email_url(email)

本质上,取消订阅方法移动到控制器。应该很简单。请注意,此调用仅生成要在用户单击 link 时调用的 URL,它实际上并未进行调用。您当前的代码正在调用。