Using Rails 4, I want to use Ajax form post using :remote => true and I want to be able to get back the response in json format so I can make use of any error messages in case of failure.
The form post is hitting my controller action fine. Controller action:
def create
@ment_hash = ment_params
@obj = @ment_hash[:mentable_type].constantize.find(@ment_hash[:mentable_id])
@ment = Comment.build_from(@obj, current_user.id, @ment_hash[:body])
respond_to do |format|
if @ment.save
if @ment_hash[:reply_to].to_i > 0
@parentment = Comment.find(@ment_hash[:reply_to].to_i)
@ment.move_to_child_of(@parentment)
end
format.js { render :template => "ments/create.js.erb", :status => :created }
else
format.js { render :template => "ments/create.js.erb", :status => :unprocessable_entity }
end
end
end
The controller action will render the create.js.erb regardless of success or error as expected. But if I include format.json it will never respond using json. I think this is because Ajax remote: true requests will always respond using js.
How do I get the ajax request to respond with json?
With this observation that rails ajax requests respond with js format, I am further confused by the example provided here: .html where the successful save response provides the js format but the error response does not provide any js format.
I would think this would error for an ajaxError response because the js format is not available?:
def create
@user = User.new(params[:user])
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.js {}
format.json { render json: @user, status: :created, location: @user }
else
format.html { render action: "new" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
Using Rails 4, I want to use Ajax form post using :remote => true and I want to be able to get back the response in json format so I can make use of any error messages in case of failure.
The form post is hitting my controller action fine. Controller action:
def create
@ment_hash = ment_params
@obj = @ment_hash[:mentable_type].constantize.find(@ment_hash[:mentable_id])
@ment = Comment.build_from(@obj, current_user.id, @ment_hash[:body])
respond_to do |format|
if @ment.save
if @ment_hash[:reply_to].to_i > 0
@parentment = Comment.find(@ment_hash[:reply_to].to_i)
@ment.move_to_child_of(@parentment)
end
format.js { render :template => "ments/create.js.erb", :status => :created }
else
format.js { render :template => "ments/create.js.erb", :status => :unprocessable_entity }
end
end
end
The controller action will render the create.js.erb regardless of success or error as expected. But if I include format.json it will never respond using json. I think this is because Ajax remote: true requests will always respond using js.
How do I get the ajax request to respond with json?
With this observation that rails ajax requests respond with js format, I am further confused by the example provided here: http://edgeguides.rubyonrails/working_with_javascript_in_rails.html where the successful save response provides the js format but the error response does not provide any js format.
I would think this would error for an ajaxError response because the js format is not available?:
def create
@user = User.new(params[:user])
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.js {}
format.json { render json: @user, status: :created, location: @user }
else
format.html { render action: "new" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
Share
Improve this question
asked Jul 30, 2015 at 23:40
joshweirjoshweir
5,6473 gold badges42 silver badges65 bronze badges
1 Answer
Reset to default 8The controller action will render the create.js.erb regardless of success or error as expected. But if I include format.json it will never respond using json. I think this is because Ajax remote: true requests will always respond using js
First off, your assumption is incorrect. Rails remote: true
hooks into what's known as the UJS driver, which makes a lot of the work involved in making an XHR request simpler. However, you could achieve the same behaviour by having a form_for
or form_tag
and handling the form submission purely in JS via jQuery's excellent $.ajax()
.
I'd suggest you first delete the create.js.erb
- this will always be processed to return a script response, and you want to render JSON instead.
You can also be a bit more explicit here,
format.json { render json: { @user, status: :created, location: @user } }
Under the covers, Rails is calling #to_json
on your Ruby objects such as AR models, to simple Hashes.
Once you've removed the create.js.erb
, go the view where you are rendering your form. Look for the form
element in the DOM, you can casually look for it via the inspector console via $('form')
. It's better to identify it via a class or directly, its id. Let's assume your form's selector is $('#ments-form')
.
You'll want to add another JS file to your app/assets/javascripts/application.js
Sprockets manifest, and inside that file
$(function(){
var $mentForm = $('#ments-form');
$mentForm.on('ajax:error', function(e, xhr, status, error) {
console.log('Error: %O', $(this).append(xhr.responseText));
});
$mentForm.on('ajax:success', function(e, data, status, xhr) {
console.log('Data: %O', data);
});
});
The JS snippet above is a start, and will fire when those jquery-ujs events are triggered, placing debugging output into the console. On an XHR error, you'll get error info, on success the JSON data will be shown instead.
Addendum:
The format.js
in the respond_to block is purely for processing the create.js.erb
, which in the example provided does this $("<%= escape_javascript(render @user) %>").appendTo("#users");
- it uses the user instance to figure out the DOM selector, and appends that to a DIV with id 'users' into the DOM.
Personally, I find it's simpler to stick to JSON for consistencies sake and achieve the same behaviour via the success handler, although YMMV.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745091404a4610714.html
评论列表(0条)