Rails通过Unsubscribe链接发送电子邮件

时间:2015-12-22 04:41:49

标签: ruby-on-rails email unsubscribe

我正在开发一个Rails 4.2应用程序,该应用程序包含人们注册的每周重复活动。他们将在每个活动之前收到提醒电子邮件(每周一次)。我想在电子邮件上单击取消订阅链接。这似乎是一个常见的任务,但我还没有找到一个好的当前解决方案。我看到的一些方向是使用MessageVerifier,它是Rails 4.1的新功能,不需要保存令牌字符串以与数据库中的比较。有什么步骤来实现这一目标。我有一个用户模型和一个事件模型。电子邮件将发送给注册了定期活动的注册用户。

2 个答案:

答案 0 :(得分:42)

以下是我提出的用于发送给订阅者的常规电子邮件的取消订阅链接的解决方案。它使用MessageVerifier。

1。生成user.id

的加密哈希

在我的事件控制器中,我有一个发送电子邮件的send_notice操作。我将为取消订阅链接创建一个变量并将其传递给邮件程序。

# app/controller/events_controller.rb
def send_notice
  ...
  @unsubscribe = Rails.application.message_verifier(:unsubscribe).generate(@user.id)
  EventMailer.send_notice(@event, @user, @unsubscribe).deliver_later
end

这将获取用户ID并生成带符号和编码的字符串变量@unsubscribe。消息验证程序通过将用户id与您的secret_key_base(在文件config / secrets.yml中找到)以及您给出消息的名称(在这种情况下,我调用它)将用户ID转换为难以理解的字符串:取消订阅,但它可以是任何名称),因为他们称之为盐,并通过一个名为SHA1的算法运行它。确保您的secret_key_base保持安全。使用环境变量将值存储在生产中。 在最后一行,我们将@unsubscribe变量与@event和@user变量一起传递给邮件程序。

2。将@unsubscribe哈希变量添加到邮件程序

# app/mailers/event_mailer.rb
def send_notice(event, user, unsubscribe)
  @event = event
  @user = user
  @unsubscribe = unsubscribe
  mail(to: user.email, subject: "Event Info")
end 

3。将取消订阅链接放在电子邮件中

# app/views/events_mailer/send_notice.html.erb
...
<%= link_to "Unsubscribe", settings_unsubscribe_url(id: @unsubscribe) %>.

注意添加了(id:@unsubscribe)参数。这会将编码的用户ID附加到以#开头的URL的末尾。在所谓的查询参数中。

4。添加路线

添加将用户带到取消订阅页面的路线。然后他们提交取消订阅的另一条路线。

# config/routes.rb
get 'settings/unsubscribe'
patch 'settings/update'

5。将订阅字段添加到用户模型

我选择在用户模型中添加一个预订boolean(true / false)字段,但您可以通过多种方式设置它。 rails g migration AddSubscriptionToUsers subscription:boolean

6。 Controller - 从URL

解码user_id

我选择添加一个带有取消订阅和更新操作的设置控制器。生成控制器rails g controller Settings unsubscribe。 当用户点击电子邮件中的取消订阅链接时,它将转到URL并将编码的用户ID附加到问号后作为查询参数的URL。以下是链接的示例:http://localhost:3000/settings/unsubscribe?id=BAhpEg%3D%3D--be9f8b9e64e13317bb0901d8725ce746b156b152。 取消订阅操作将使用MessageVerifier来取消签名并解码id参数以获取实际的用户ID,并使用它来查找用户并将其分配给@user变量。

# app/controllers/settings_controller.rb
def unsubscribe
  user = Rails.application.message_verifier(:unsubscribe).verify(params[:id])
  @user = User.find(user)
end

def update
  @user = User.find(params[:id])
  if @user.update(user_params)
    flash[:notice] = 'Subscription Cancelled' 
    redirect_to root_url
  else
    flash[:alert] = 'There was a problem'
    render :unsubscribe
  end
end

private
  def user_params
    params.require(:user).permit(:subscription)
  end

7。观点

添加包含表单的取消订阅页面以取消订阅。

# app/views/settings/unsubscribe.html.erb
<h4>Unsubscribe from Mysite Emails</h4>
<p>By unsubscribing, you will no longer receive email...</p>
<%= form_for(@user, url: settings_update_path(id: @user.id)) do |f| %>
  <%= f.hidden_field(:subscription, value: false) %>
  <%= f.submit 'Unsubscribe' %>
  <%= link_to 'Cancel', root_url %>
<% end %>

您可以通过多种方式进行设置。在这里,我使用form_for帮助程序路由到settings_update_path,并添加了一个id:@ user.id参数。这将在将表单作为查询参数发送时将用户标识附加到URL。 Update操作将读取它以查找用户并将Subscription字段更新为false。

答案 1 :(得分:2)

一个非常好的选择可能是使用Michael Hartl的Rails教程应用程序。在chapter 12中,他实现了一个用户可以关注其他用户微博的系统(基本上是推文,推特风​​格)。您只需要设置模型验证(用户和事件模型)并实现关系模型&amp;控制器。关系模型和控制器处理整个跟随机制。本质上,控制器只有创建和删除操作,创建操作用于创建关系,销毁用于删除它。要处理取消订阅方案,您只需让rails在ActionMailer模板中呈现删除路径即可。上面的链接为您提供分步说明,但如果您迷路了,请随时向我提问。