I currently have a login popup in my header bar which is on every page in my website. I want to be able to reload the current page that the person is on after a successful login. How do I do this in the controller?
def create
#declaring and defining user variable stuff
if user.save
#reload current page <--how do I do this?
end
end
Thanks
For my application, I use redirect_to :back and it does the trick. However, I doubt this might have an error in a non general use case(s) (user came from a special page?) but i haven't found it so far in my app.
If you're looking for a way to get the page to refresh (typically redirect_to :back) with an XHR request, you don't have to look for a way to change the response type - just tell the page to reload with inline JS.
format.js { render inline: "location.reload();" }
Like Elena mentions, this should go in a respond_to block, like so:
respond_to do |format|
format.js {render inline: "location.reload();" }
end
In Rails 5 redirect_to :back is improved by:
redirect_back(fallback_location: root_path)
Since Rails 5 (or maybe older versions), you have a request.referrer method. You simply redirect from controller to referrer and it opens the page where request came from.
redirect_to request.referrer, notice: "You're being redirected"
Archonic's answer above worked for me. However, in Rails 3, I had to place this in a respond_to block in order to avoid an 'ArgumentError (too few arguments)' error:
respond_to do |format|
format.js {render inline: "location.reload();" }
end
Rails 5 introduced alternative function:
redirect_back(fallback_location: root_path)
It redirect back whenever the HTTP_REFERER is known.
Otherwise it redirects to the fallback_location.
The redirect_to :back is deprecated in Rails 5.0 https://github.com/rails/rails/pull/22506 and removed since Rails 5.1
This syntax is what you want... works in Rails 6
respond_to do |format|
format.html { redirect_to request.referrer, notice: "User was successfully WHATEVER." }
end
Building on Archonic's and Elena's Answers, the reload function accepts a parameter to force the page to reload from the server aka forceGet, instead of from cache. A parameter can be set by the controller logic, like successful or failed login of a user, to trigger the desired behavior when it is sent to the page.
# force_get = controller_logic ? true : false
respond_to do |format|
format.js { render inline: "location.reload(#{force_get});" }
end
UPDATE:
the logic has been deprecated for the forceGet option. If you do want to reload from the server you can use this logic:
# force_get = controller_logic ? true : false
respond_to do |format|
format.js { render inline: force_get ? "window.location.href = window.location.href;" : "location.reload();" }
end
just redirect to whatever url you want in the function:
redirect_to what_ever_path
Related
am doing redirecting in my controller action something like this
format.html { redirect_to product_path(#product) }
which is taking me to PUT /products/123456
but i would like to go GET /products/123456.
can some explain me why this is happening. what is the exact helper method should i use to go with GET request?
According to doc product_path(#product) is comon for all GET, PUT/PATCH, and DELETE.
I could not find any option to pass something like
format.html { redirect_to product_path(#product) }, method: :get
in redirect_to api doc. Please explain me how can i achieve this. thanks
Update:
def delete_product_media
#product = Product.find(params[:id])
#product_media = ProductMedium.where(id: params[:product_media_ids])
respond_to do |format|
if #product_media.update_all(deleted_at: Time.zone.now) == params[:product_media_ids].count
flash[:notice] = 'Media deleted'
flash.keep(:notice)
format.html { redirect_to product_path(#product), method: :get }
else
flash[:notice] = 'Something went wrong!'
flash.keep(:notice)
format.html {redirect_to product_path(#product) }
end
end
end
A redirect with redirect_to (default HTTP 302 Found) which should persist the method, allthough does not always. You can use 303 See Other if you want to force a GET.
See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302
Even if the specification requires the method, and the body, not to be altered when the redirection is performed, not all user-agents conform here, and you can still find buggy software out there. It is therefore recommended to set the 302 code only as a response for GET or HEAD methods and to use 307 Temporary Redirect instead, as the method change is explicitly prohibited in that case.
In the cases where you want the method used to be changed to GET, use 303 See Also instead. This is useful when you want to give an answer to a PUT method that is not the uploaded resource, but a confirmation message (like "You successfully uploaded XYZ").
For redirect_to the status option overrides the default, e.g. redirect_to product_path(#product), status: :see_other.
You could do redirect_to #products if you want to redirect to show page . Which will be processed like GET /products/123456 .
When there was an error on updating my model, I was rendering :edit, but this was stripping the /edit from my url because #update is the same as #show with a different request method. To solve this I tried following the advice given here, but this caused me to get an ActionDispatch::Cookies::CookieOverflow error when I try to submit an invalid form. How should I correctly re render the edit page, while keeping both the /edit url and the flash messages? Is it possible to check for validity and show the errors without making a call to update?
Original code:
def edit
end
def update
respond_to do |format|
format.html do
if #model.update(model_params)
redirect_to home_base_url_or_default(model_url(#model)), notice: "Successfully updated."
else
render :edit
end
end
end
end
Failing code:
def edit
if flash[:model]
#model = flash[:model]
end
end
def update
respond_to do |format|
format.html do
if #model.update(model_params)
redirect_to home_base_url_or_default(model_url(#model)), notice: "Successfully updated."
else
flash[:model] = #model
redirect_to :action => :edit
end
end
end
end
Rather than doing a redirect, in this case the problem was solved by doing a render, then controlling the view by setting an instance var in the controller saying if it is the edit page or not. Also by using the update class in the CSS. However, this still has the the url for the show page, but at least the layout is correct.
One way to do it would be to allow the edit action to accept the POST method as well. Use request.method to check whether it is a POST or GET, then perform your render or redirect accordingly.
Right now, I have a rails ajax request on submission of a form, which has the following success code:
if #event.save
...
respond_to do |format|
format.js { render 'draw_calendar' }
format.html { redirect_to show_calendar_path }
end
end
I need to add some code that, if a new flag is set on the form, will spawn the creation of a new, follow-up form for a different model that (of course) should be governed by a different controller. Thus what I want to do is, if #event gets saved successfully, check that flag (easy), and if it's set, redirect to another controller action. First, will that even work in the browser if it was an ajax request (format.js)? And second, will the browser then successfully render whatever gets sent back from the new controller action?
Yes, browser always follow redirect in ajax request
if #event.save
if #event.something?
redirect_to some_other_path(format: params[:format])
return
end
respond_to do |format|
format.js { render 'draw_calendar' }
format.html { redirect_to show_calendar_path }
end
end
If you need to detect redirect in javascript code I usually add custom header
response.headers['X-XHR-Current-Location'] = request.fullpath
def destroy
#project = Relationship.find(params[:id]).followed
current_user.unfollow!(#project)
respond_to do |format|
format.html { params[:page]? (redirect_to "#{params[:page]}_path") : (redirect_to #project ) }
format.js
end
end
in above code if i pass params[:page] = "dashboard" then it should redirect to dashboard_path but currently it redirects to localhost:3000dashboard_path
i know where is the problem ("#{params[:page]}_path" returns a string rather than a path) but i want the solution bcoz i dont know how to fix this.
thanks a lot.
I think this will work
redirect_to send("#{params[:page]}_path")
or full version is
format.html { params[:page] ? redirect_to(send("#{params[:page]}_path")) : redirect_to(#project) }
Such dependency on param is unnecessary in my opinion.
It's you who write the controller, it's also you who define such query string in previous page.
So, why not redirect_to dashboard_path directly if that's all of your desired logic?
Suppose you have an edit form with :remote => true. Your controller method looks like
def update
#article = Article.find(params[:id])
respond_to do |format|
if #article.update_attributes(params[:article])
format.html { redirect_to #article}
format.js { render :js => "window.location.replace('#{article_path(#article)}');"}
else
format.html { render :action => "edit" }
# Render update.js.erb which replaces the body of the form
format.js {}
end
end
end
What's the best way to do the redirect on successful article update in Rails 3.2.1? The raw JS solution seems a little sleazy, but I do like the fact that it's obvious that it's performing the same function as the format.html version.
I would prefer a solution that does not use RJS (if that even works in Rails 3.2?)
How about adding the below line of code on the view file itself
#some_file.js.erb
`window.location = redirect_path
As you mentioned in the question you do not prefer RJS, but I think it's better to follow this pattern better than writing the js code in the controller.
Does your ajax interact with a model (.php,.asp?). My preferred method in this instance is to create a success/fail criteria within the model after submission and redirect directly from there. Not sure if that makes sense in this application though?