Here is a solution I developed to link to unsubscribe from regular emails sent to subscribers. It uses MessageVerifier.
1. Create a cryptographic hash of user.id
In my event controller, I have a send_notice action that sends an email. I will create a variable for the unsubscribe link and pass it to the mailer.
This takes a user id and generates a signed and encoded @unsubscribe string variable. The message verifier turns the user ID into an illegible character string, mixing it with your secret_key_base (found in the config / secrets.yml file) and the name you pass to this message (in this case I call it: unsubscribe, but it can be any name) like what they call a salt, and run it through the SHA1 algorithm. Make sure your secret_key_base is safe. Use environment variables to store value in production. In the last line, we pass the @unsubscribe variable to the mailer along with the @event and @user variables.
2. Add the @unsubscribe hash variable to the mailbox
3. Put the unsubscribe link in the email
# app/views/events_mailer/send_notice.html.erb ... <%= link_to "Unsubscribe", settings_unsubscribe_url(id: @unsubscribe) %>.
Note the argument added (id: @unsubscribe). This will add a coded user ID to the end of the URL starting with? in the so-called query parameter.
4. Add routes
Add a route where the user goes to the unsubscribe page. Then another route when they send an unsubscribe.
# config/routes.rb get 'settings/unsubscribe' patch 'settings/update'
5. Add a subscription field to the user model
I decided to add a boolean field (true / false) to subscribe to the user model, but you can configure it in different ways. rails g migration AddSubscriptionToUsers subscription:boolean .
6. Controller - decodes user_id from URL
I decided to add a settings controller with canceled subscription and update action. Generate rails g controller Settings unsubscribe . When the user clicks on the unsubscribe link in the email, he will go to the URL and add the encoded user ID to the URL after the question mark as a request parameter. Here's an example of what the link will look like: http: // localhost: 3000 / settings / unsubscribe? Id = BAhpEg% 3D% 3D - be9f8b9e64e13317bb0901d8725ce746b156b152 . The unsubscribe action will use MessageVerifier for unauthorized access and decoding the identity parameter to get the actual user ID and use it to find the user and assign it the @user variable.
7. Views
Add the unsubscribe page that includes the unsubscribe form.
# 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 %>
There are several ways to fix this. Here I use form_for helper redirected to path_update_path with id argument added: @ user.id. This will add the user id to the url when submitting the form as a request parameter. The Update action will read it to find the user and update the Subscription field to false.