Respond_With Redirect with Notice Flash Message Not Working

respond_with redirect with notice flash message not working

I discovered the problem.

flash[:notice]="...." is properly working on the create action, redirecting to the show action.

What I forgot was that my 'show' consists on a redirect to edit.

I fixed this by implementing the show action like this:

def show
redirect_to edit_subscription_path(@subscription),flash
end

From Rails 3.1 on, this should be accomplished with:

def show
flash.keep
redirect_to edit_subscription_path(@subscription)
end

Alert flash message not working with respond_with

Ok I figured it out. It turned out that with validation errors flash was properly set, but it was flash.now instead of flash and after redirect_to flash was deleted. The solution is to use :flash_now => false like so:

respond_with(@organization_user, :flash_now => false) do |format|
format.html { redirect_to edit_organization_path(@organization) }
end

Rails respond_to redirect not working

remote: true is an ajax request.

Ajax is javascript, and as such will invoke the format.js method:

def create
@store = current_user.stores.new store_params

respond_to do |format|
if @store.save
format.js
format.html { redirect_to root_path }
else
format.js
format.html { flash[:alert] = "Save failed! #{@store.errors.full_messages.join(";")}"
render "new" }
end
end
end

The format.js method will call the /app/views/[:controller]/[:action].js.erb file, which will fire any of the JS you have inside it.

If you don't want to have the js format handling the response, you'll have to do away with respond_to and just have what you'd like to return (redirect_to won't work).


Ajax

There are several stipulations you need to appreciate with this:

  • Ajax cannot "redirect" (on its own)
  • Ajax will be treated as JS in your Rails controller
  • You have to "hack" the flash to get it working through JS

If you don't have experience with Ajax, the simple explanation is that it's a "pseudo-request"; it sends an HTTP request without having to reload the browser.

The pattern for Ajax is simple: Ajax request > server > Ajax response

You cannot "redirect" via Ajax unless you parse the response with javascript. As the Ajax acronym (Asynchronous Javascript And XML) suggests, the response is expected to be XML (IE no functionality).

--

To answer your question, you'll need to use flash.now for the "flash" message, and handle the response with your .js.erb file:

def create
@store = current_user.stores.new store_params
flash.now[:alert] = "Save failed! #{@store.errors.full_messages.join(";")}" unless @store.save

respond_to do |format|
format.js
format.html
end
end

This will allow you to call...

#app/views/stores/create.js.erb
<% if flash.now[:alert] %> alert("<%=j flash.now[:alert] %>"); <% end %>
window.location.href = <%= root_url %>;

Ref


Your new code can be improved a little :

def create
@store = current_user.stores.new store_params

if @store.save
flash[:notice] = "New store created"
else
flash.now[:alert] = "Save failed! #{@store.errors.full_messages.join(";")}"
end

respond_to do |format|
format.js
end
end

If you wanted to DRY up your code even more, you'll want to look at the responders gem:

#app/controllers/stores_controller.rb
class StoresController < ApplicationController
respond_to :js, only: :create

def create
@store = ...
respond_with @store if @store.save
end
end

How to set custom flash with respond_to in Rails

You should use redirect_to differently :

redirect_to photo_path(photo), :flash => { :success => "Yeepee!" }

The only flashes you can use directly are

  • :notice
  • :alert
  • :error

Hope that helps

Losing flash values after location.reload()

You lose it because you're reloading the page.

Why do you need to reload? If it's to show the new record you can just have a create.js.erb file that appends or prepends the new record.

Rails respond_with correctly shows form with validation but with index path URL

This is standard behaviour in Rails. respond_with, which isn't a core part of Rails but provided by a gem called responders, follows the same patterns as Rails' core behaviour.

When using Rails' RESTful resource pattern (e.g., if you specify resources :services in your config/routes.rb), the form data is sent in an HTTP POST request to the /services endpoint. The Rails router then converts the form data to the params object and passes that data to the ServicesController#create method to handle.

If that data turns out to be invalid, the server can't redirect to show the new form again, because to do so would lose the form data that you just submitted - and generally we want to redisplay that. So the usual course of action is to re-render the same page template as the user saw in /services/new, but with the partially complete, invalid copy of @service instead of a completely empty one.

Because no redirect occurs, the browser URL bar shows /services, because that's the endpoint that's returned the HTML the user is looking at. But the form is still representing a new, as-yet-unsaved record, and submitting it (hopefully with amendments that make the record valid) will go to POST /services just as they did the first time.

Testing Rails 3 respond_with with RSpec

Pretty funny, just tried and indeed the response doesn't contain much.

It's a mere status 302. Test: response.status.should eq 302

With a body like:

"<html><body>You are being <a href=\"new_url">redirected</a>.</body></html>"

which is easily testable too.

I'll dig a little further.


Edit:

Even with render_views, response remains a mere redirect.

You could also check response.header which looks like:

{"Location"=>"http://test.host/users", "Content-Type"=>"text/html; charset=utf-8"}

Performing a redirect from a spring MVC @ExceptionHandler method

Note that this is actually supported out-of-the-box by Spring 4.3.5+ (see SPR-14651 for more details).

I've managed to get it working using the RequestContextUtils class. My code looks like this

@ExceptionHandler(MyException.class)
public RedirectView handleMyException(MyException ex,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
String redirect = getRedirectUrl(currentHomepageId);

RedirectView rw = new RedirectView(redirect);
rw.setStatusCode(HttpStatus.MOVED_PERMANENTLY); // you might not need this
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
if (outputFlashMap != null){
outputFlashMap.put("myAttribute", true);
}
return rw;
}

Then in the jsp page I simply access the attribute

<c:if test="${myAttribute}">
<script type="text/javascript">
// other stuff here
</script>
</c:if>

Hope it helps!



Related Topics



Leave a reply



Submit