The respond_to block in a create controller in my Rails app is not redirecting on a successful save... I'm sure this is a simple solution, but I am inexperienced with Rails and this is the first time that I am encountering this problem.
The form is set so that :remote => true, and the controller is as follows...
def create
@store = current_user.stores.new(store_params)
respond_to do |format|
if @store.save
format.html { redirect_to root_path }
else
format.html { flash[:alert] = "Save failed! #{@store.errors.full_messages.join(";")}"
render "new" }
format.js {}
end
end
end
And while I'm on the subject, the code from the else portion of the conditional doesn't run either, except for format.js {}
, which does run the code in my create.js.erb file (an alert, for the time being).
I'm working with Rails 4.2.5. Can someone help me to understand why the redirect and the alert are not working? Thank you!
EDITING TO SHOW SOLUTION Based on Rich's answer, here's the solution that I came up with:
Controller:
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
end
if @store.save
flash[:notice] = "New store created"
end
end
create.js.erb
<% if flash.now[:alert] %>
$("#alert_holder").empty();
$("#alert_holder").append("<%= j flash.now[:alert] %>");
<% else %>
window.location.href = "<%= root_url %>";
<% end %>
Note that I needed to add quotes around the redirect url.
On form success, the page redirects to root. On failure, the error message flashes but the form is not refreshed - any answers the user has entered remain.
remote: true
is an ajax request.Ajax is javascript, and as such will invoke the
format.js
method: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 withrespond_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:
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:This will allow you to call...
Ref
Your new code can be improved a little :
If you wanted to
DRY
up your code even more, you'll want to look at theresponders
gem: