I am using Devise with Rails for my user login. It all works great, however, i am unable to get a specific redirection working.
I am new to rails so the method in which i am doing things may not be correct.
Essentially, with an example, i am allowing users to like a post. However, they need to be signed in to do so. I have created an action in my controller called 'like' and the controller has the devise filter
before_filter :authenticate_user!, :except => [:index, :show]
entered thereby the sign in page is being shown. Once the user signs in i want to redirect them back to the post which they have liked with the 'like' action having been called.
my controller looks like
def like
@post = Post.find(params[:id])
@like = Like.new;
@like.user_id = current_user.id;
@like.post_id = params[:id];
respond_to do |format|
if @like.save
format.html { redirect_to @post, notice: 'You have like this post' }
format.json { head :no_content }
else
format.html { redirect_to @post, notice: 'Sorry you like was not saved }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
Naturally i cannot hard code the path using after_sign_in_path_for
def after_sign_in_path_for(resource)
#path to somewhere
end
But i have read that i can use a session variable and perhaps call that in the above code. In which part of Rails could i write the session variable, as it would be too late in the controller action (as devise takes over before it hits the like action) and i cannot see how to set it in the view.
Also my link looks like
<%= link_to "Like", {:controller => :posts, :action => :like, :id => @post.id}, {:method => :post } %> |
PS the redirection when using creating a new 'post' works ok i.e. the user signs in and are redirected to the new post view.
Any help and tips would be greatly appreciated.
Thanks
You are experiencing this because like action is specifically designed for POST. Therefore, you should make sure that user is signed in before you POST to that URL, and doing it with session is tricky:
before_filter
user_signed_in?
(mind you this is a helper method), Seeing that all of this dance will end with a GET request, why not make Like action work on GET requests as well as pass parameters in the Query String in the first place? It will require 0 code changes and it will not expose you to a security threat since Like is protected by before_filter. You would just have to make sure that your Like links aren't followed by search engines by using rel="nofollow" on your <a>
tags.
For a related discussion, see redirect_to using POST in rails. There, one of the suggestions is to build and submit a form on the client via JavaScript. That would have to happen on that return URL view once user has authenticated. This might be the best compromise if you object to having your like action exposed as GET (which violates REST principles)