Reputation: 2142
I have a Rails controller set up that when a user creates a new record, it will redirect again to the new action and populate the form with new data, and this can continue on in a loop, creating a new record and getting redirected to the new action. What I am having trouble with is adding AJAX to this so that the user can stay in this loop without the page reloading. Here is my code without AJAX:
class ResponsesController
def new
@response = Response.new
@answer_a = Answer.find(rand(1..100))
@answer_b = Answer.find(rand(1..100))
@answer_c = Answer.find(rand(1..100))
end
def create
@response = current_user.responses.build(params[:response])
if @response.save
respond_to do |format|
format.html { redirect_to new_response_path }
format.js
end
else
render 'new'
end
end
end
new.html.erb
<div id="response_form">
<%= render 'form' %>
</div>
_form.html.erb
<%= form_for @response do |f| %>
<%= f.radio_button :user_answer, @answer_a.id %>
<%= @answer_a.description %>
<%= f.radio_button :user_answer, @answer_b.id %>
<%= @answer_b.description %>
<%= f.radio_button :user_answer, @answer_c.id %>
<%= @answer_c.description %>
<%= f.submit "Answer" %>
<% end %>
Below is my attempt to add AJAX. However, it is going to the show action and doing an update. How can I fix my code so that it keeps redirecting to the new action and the user can continue to create new records on an infinite loop?
def create
@answer_a = Answer.find(rand(1..100))
@answer_b = Answer.find(rand(1..100))
@answer_c = Answer.find(rand(1..100))
@response = current_user.responses.build(params[:response])
if @response.save
respond_to do |format|
format.html { redirect_to new_response_path }
format.js
end
else
render 'new'
end
end
_form.html.erb
<%= form_for @response, :remote => true do |f| %>
<%= f.radio_button :user_answer, @answer_a.id %>
<%= @answer_a.description %>
<%= f.radio_button :user_answer, @answer_b.id %>
<%= @answer_b.description %>
<%= f.radio_button :user_answer, @answer_c.id %>
<%= @answer_c.description %>
<%= f.submit "Answer" %>
<% end %>
create.js.erb
$('#response_form').html('<%= j render("form") %>');
Upvotes: 0
Views: 1212
Reputation: 19203
The code seems fine by me. It shouldn't be redirecting to the show action. Make sure that:
You have gem 'jquery-rails'
in your Gemfile
You have <%= javascript_include_tag 'application' %>
in your application.html.erb
file
You have the following lines in your application.js
file
//= require jquery
//= require jquery_ujs
Ok, so the problem here is that you are including the line <%= form_for @response do |f| %>
inside the _form
partial. Why is that a problem? Well, when an object @response
does not exist, Rails renders the form like this:
<form accept-charset="UTF-8" action="/responses" method="post">
When an object @response
does exist, Rails renders the form like this:
<form accept-charset="UTF-8" action="/responses/id_of_the_response" method="post">
Rails does this because it knows that @response
exists so it's only logical that you want to update it (and not create it again).
The solution here is to change the form_for to this:
<%= form_for @response, :url => { :action => :create, :method => :post } do |f| %>
Also, be mindful that build
is not saving the @response
object.
Upvotes: 3