简体   繁体   中英

Rails Devise redirect after login

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 ie 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:

  • You'd have to unprotect like method by excluding it from before_filter
  • Then check manually if user_signed_in? (mind you this is a helper method),
  • Then (if user is not signed in), stash what you are liking in session and redirect to sign in page with return URL
  • Upon user visiting this return URL (it will be a GET and not a POST ), you would have to look up the session info and do what original Like was supposed to do (but by then user will be signed in).

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)

this is easy to fix:

go in application controller:

 # after login redirect
 after_filter :store_location

 def store_location
   # previous url save when its not a admin or user url
   session[:previous_url] = request.fullpath unless request.fullpath =~ /\/users/ || request.fullpath =~ /\/admin/ || request.fullpath =~ /\/admin\/login/ || 
   request.fullpath =~ /\/login/
 end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM