【问题标题】:Rails unsubscribe link with ActionMailerRails 使用 ActionMailer 取消订阅链接
【发布时间】:2016-03-04 05:03:35
【问题描述】:

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

电子邮件模型:

    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_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

【问题讨论】:

    标签: ruby-on-rails email actionmailer


    【解决方案1】:

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

    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
    

    这处理控制流。

    在视图中,链接变为:

    unsubscribe_email_url(email)
    

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

    【讨论】:

    • 关于 :member,这是我声明的东西吗?电子邮件还是来自 rails 的东西?
    • 我认为这行得通,但我看到模板错误。我假设那是因为我没有在我的取消订阅方法中设置句柄错误、成功重定向等?
    • 对,你需要有一个名为 unsubscribe.erb 的视图,或者成功时重定向它。
    • 感谢您的帮助并解释了完成这项任务应该做什么!
    • :member 是一种 Rails 路由方法,它在 RESTful 资源(如显示、索引、编辑、销毁等)上定义了附加路由。像显示和编辑这样的路由是“成员”动作——也就是说,它们作用于资源的特定实例(在这种情况下,是一封电子邮件)。还有一些类似 index 的路由作用于所有资源;这些是“收集”动作。声明成员路由也可以获得资源方法;这就是 unsubscribe_email_url 起作用的原因。
    【解决方案2】:

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

    您的link_to 也没有任何意义,看起来您正在尝试路由到您的模型,这些是不可路由的。它应该是指向控制器操作的链接,例如 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

    【讨论】:

    • 这个答案是不完整的,因为视图代码阻止了任何工作。但这似乎是在控制器而不是模型中完成的事情......
    • 我认为你是对的。该模型根本不应该有取消订阅方法。这不是真正的业务逻辑。
    猜你喜欢
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 2013-11-20
    • 2017-01-24
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多