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,它实际上并未进行调用。您当前的代码正在调用。
我有一个电子邮件模型供用户注册,以便在添加或更新文章时接收电子邮件通知。电子邮件正常工作,但我收到一条错误消息,其中包含我在 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,它实际上并未进行调用。您当前的代码正在调用。