我正在开发一个Rails 4.2应用程序,该应用程序包含人们注册的每周重复活动.他们将在每个活动之前收到提醒电子邮件(每周一次).我想在电子邮件上单击取消订阅链接.这似乎是一个常见的任务,但我还没有找到一个好的当前解决方案.我看到的一些方向是使用MessageVerifier,它是Rails 4.1的新功能,不需要保存令牌字符串以与数据库中的比较.有什么步骤来实现这一目标.我有一个用户模型和一个事件模型.电子邮件将发送给注册了定期活动的注册用户.
这是我提出的用于发送给订阅者的常规电子邮件的取消订阅链接的解决方案.它使用MessageVerifier.
在我的事件控制器中,我有一个发送电子邮件的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中找到)以及您给出消息的名称(在这种情况下我称之为:取消订阅但是它可以是任何名称),因为它们称为盐,并通过称为SHA1的算法运行它.确保您的secret_key_base保持安全.使用环境变量将值存储在生产中.在最后一行,我们将@unsubscribe变量与@event和@user变量一起传递给邮件程序.
# 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
# app/views/events_mailer/send_notice.html.erb ... <%= link_to "Unsubscribe", settings_unsubscribe_url(id: @unsubscribe) %>.
注意添加了(id:@unsubscribe)参数.这会将编码的用户ID附加到以#开头的URL的末尾.在所谓的查询参数中.
添加将用户带到取消订阅页面的路由.然后他们提交取消订阅的另一条路线.
# config/routes.rb get 'settings/unsubscribe' patch 'settings/update'
我选择将订阅boolean(true/false)字段添加到用户模型,但您可以通过许多不同的方式设置它.rails g migration AddSubscriptionToUsers subscription:boolean
.
我选择添加一个带有取消订阅和更新操作的设置控制器.生成控制器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
添加包含表单的取消订阅页面以取消订阅.
# app/views/settings/unsubscribe.html.erbUnsubscribe from Mysite Emails
By unsubscribing, you will no longer receive email...
<%= 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.