Try associating each client with a unique, but obscure, identifier which can be used to look up (and unsubscribe) the user via the unsubscribe link contained within the email.
Start by adding another column to your clients table called unsubscribe_hash
:
# from command line
rails g migration AddUnsubscribeHashToClients unsubscribe_hash:string
Then, associate a random hash with each client:
# app/models/client.rb
before_create :add_unsubscribe_hash
private
def add_unsubscribe_hash
self.unsubscribe_hash = SecureRandom.hex
end
Create a controller action that will toggle the subscription
boolean to true
:
# app/controllers/clients_controller.rb
def unsubscribe
client = Client.find_by_unsubscribe_hash(params[:unsubscribe_hash])
client.update_attribute(:subscription, false)
end
Hook it up to a route:
# config/routes.rb
match 'clients/unsubscribe/:unsubscribe_hash' => 'clients#unsubscribe', :as => 'unsubscribe'
Then, when a client object is passed to ActionMailer, you'll have access to the unsubscribe_hash
attribute, which you can pass to a link in the following manner:
# ActionMailer view
<%= link_to 'Unsubscribe Me!', unsubscribe_url(@user.unsubscribe_hash) %>
When the link is clicked, the unsubscribe
action will be triggered. The client will be looked up via the passed in unsubscribe_hash
and the subscription
attribute will be turned to false
.
UPDATE:
To add a value for the unsubscribe_hash
attribute for existing clients:
# from Rails console
Client.all.each { |client| client.update_attribute(:unsubscribe_hash, SecureRandom.hex) }
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…