简体   繁体   中英

Continue Form Post with remote => true / Controller Action after Devise Login

I'm trying to do something very similar to this question ...

In summary, I have voting logic on a page, but to vote, I require you to sign in. The voting logic for a signed in user simply does a :method => :post, :remote => true call to a controller method, saves the vote, and does a respond_to :js to a JavaScript HAML template which replaces HTML using jQuery.

For an unauthenticated user, this currently works such that the anonymous user clicks "vote", is redirected to the Devise login page, logs in, and gets redirected back to the page they were on to vote again. But, this is a bad user experience.

How would I change this so that the last step simply continues to process their vote?

I have existing HTML views for the voting logic, and would prefer to simply continue the processing of the vote, redirect to the page where the user voted from, and flash a message saying the vote was successful. However, if it's just "as easy" to do this using JavaScript / jQuery, I'd be open to this. The only piece I want to avoid is re-creating the Devise templates in JavaScript.

The difficulty in this type of redirect lies in the fact that forms are submitted via post requests. Rails' redirect_to method makes a get request, which prevents you from submitting forms.

This solution does not care about the type of authentication you use. This is what I did in the past (this is pseudo code to illustrate the process):

If the user is not signed in, attach a hidden field to the form and assign its id to a random string:

- unless signed_in?
  = hidden_field_tag :submit_token, id: "form_#{rand}" # just generate something random

In your controller filter that checks if the user is signed in, check for this param, and set a session hook if it's present.

session[:submit_token] = params[:submit_token] if params[:submit_token].present?

Then in your create.js.erb (the template that's rendered after an ajax sign in) check for this session value. If it's present, use it to find the form and submit it via jQuery.

- if session[:submit_token]
  $('#' + session[:submit_token]).parent('form').submit();
  - session[:submit_token] = nil

Ideally you would create helper methods to set and remove the session[:submit_token] values.

The reason you can't use something more traditional, like a store_location method is because they can't deal with post requests. So you can't redirect back and continue the original post request before it was diverted to the login.

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