37
votes

I am using Rails 3.2, I have a form and I want it to be posted via ajax and have the controller return json.

I am using a form_for helper like so:

= form_for(@object, :remote => true, :format => :json) do |f|
....

My objects controller create method looks like this:

  def create
    respond_to do |format|
      if @object.save
         format.html { redirect_to @object }
         format.json { render json: @object, status: :created, location: @object }
      else
        format.html { render action: "new" }
        format.json { render json: @object.errors, status: :unprocessable_entity }
      end
    end
  end

The form is submitting ajaxly as expected. But the controller is returning html, not json!

Inspecting the request with firebug and sure enough the Content-Type http header on the ajax request is being set to application/html.

The documentation around this is pretty sparse, :format => :json seems to just append ".json" to the forms action, not actually modify any http headers.

I've also tried :content_type => :json to no effect.

I can't simply hard code the controller to return json as there are other places where I do want it to return html...

So does anyone know how to tell the controller to render json when using form_for?

Thanks for any help

2
What url and method gets rendered in your form tag on the page? - iltempo
Post, the complete tag is: <form method="post" id="new_object" data-remote="true" class="new_object" action="/objects" accept-charset="UTF-8"> - Chris
No json here. Did you consider using request.xhr? to distinguish between ajax and normal requests instead of the requested format? - iltempo
OK, did a quick test and that seems to be a workaround, for now. Not sure that it is correct - surely the format and the request mechanism should be seperated. What if I want to add another ajax request later on that needs xml? - Chris

2 Answers

53
votes

You can set the content-type with:

= form_for(@object, :remote => true, :html => {:'data-type' => 'json'})

As described in rails.js line 106.

7
votes

For Rails 5, the proper way is to set a data attribute data: { type: :json }.

JQuery UJS docs