I have an ‘unsubscribe’ model where an unsubscribe record gets created when the user clicks on this link within the app:
link_to "Unsubscribe from comments on this post", post_unsubscribes_path(@post), method: :post
I would like to provide the same link in an email when the user gets notified of comments. The only problem is ‘method: post’ doesn’t work in an email (reverts to a ‘get’ request). Here is the controller:
class UnsubscribesController < ApplicationController
def create
post = Post.find(params[:post_id])
current_user.unsubscribes.create(post: post)
redirect_to post_path(post), :notice => 'You are now unsubscribed from comments on this post.'
end
end
Any ideas on how to go about doing this from an email? I googled endlessly and I can’t find anything even though this seems like it would be pretty common. Do I need to change how I go about this in the controller?
Hmm, I get an undefined method error when I try that. post_unsubscribes_path works in the app’s view, but not in the sent email because it’s trying to use rails built in javascript form magic with method: post (I think).
Here’s the current route:
resources :posts do
resources :likes, :only => [:create]
resources :unsubscribes, :only => [:create]
end
So I figured out a way to do this, I changed the route to:
resources :posts do
resources :likes, :only => [:create]
resources :unsubscribes, :only => [:index]
end
so now it will accept a get request.
Then I changed the controller to:
class UnsubscribesController < ApplicationController
before_action :authenticate_user!, :create_unsubscribe
def index
end
def create_unsubscribe
post = Post.find(params[:post_id])
current_user.unsubscribes.create(post: post)
redirect_to post_path(post), :notice => 'You are now unsubscribed from comments on this post.'
end
end
This works but it seems kind of hacky, is this a bad way to go about it?
Hey @savmac, if I understand correctly I would consider following the same pattern as Rails does with GET new and POST create. This way your email would link to the GET new path of the UnsubscribeController where you can display a summary of what is being unsubscribed and then a big Unsubscribe link/button to complete the process. This is the usual unsubscribe flow from email with other services so it’s not unfamiliar.
# config/routes.rb
resources :posts do
resources :likes, :only => [:create]
# Using resource http://stackoverflow.com/a/9194930
resource :unsubscribes, :only => [:new, :create]
end
class UnsubscribesController < ApplicationController
before_action :authenticate_user!, :set_post
def new
# Create a view for this
end
def create
current_user.unsubscribes.create!(post: post)
redirect_to post_path(post), :notice => 'You are now unsubscribed from comments on this post.'
end
private
def set_post
@post = Post.find(params[:post_id])
end
end
Unfortunately emails will only use GET routes as forms are ignored and JS is not available.
I also wonder about why you’ve gone for an opt-out pattern instead of opt-in as I would have imagined it being ‘cleaner’ to have a join table for Subscribers to Posts instead of the other way round, then you could be GET show the subscription and DELETE destroy the subscription that makes a bit more sense to me – but I don’t know enough about this project to pass any judgment in that respect
Thanks @createdbypete! Your approach is clear and makes sense.
I guess I was just looking for a way to do this in one step, similar to the way you would connect with someone from a linkedin email or even the way devise uses email/user confirmations. I think those methods though are probably a bit more complex for what is needed here by using tokens, additional fields etc.