Rails 3 remote form: How do I specify the content type?
Asked Answered
P

2

37

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

Pane answered 6/3, 2012 at 12:5 Comment(4)
What url and method gets rendered in your form tag on the page?Elva
Post, the complete tag is: <form method="post" id="new_object" data-remote="true" class="new_object" action="/objects" accept-charset="UTF-8">Pane
No json here. Did you consider using request.xhr? to distinguish between ajax and normal requests instead of the requested format?Elva
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?Pane
P
53

You can set the content-type with:

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

As described in rails.js line 106.

Purulence answered 6/3, 2012 at 12:45 Comment(5)
Thank you! Knew I was missing something obvious! :)Pane
In Rails 4 you can use format: :json (or :format => :json) instead of :html => {:'data-type' => 'json'}Jacintojack
@JamesMcMahon In Rails 3.2 either.Diction
not working in my case :( rails 4 form_for remote true not working and I'm getting this error in browser console Resource interpreted as Script but transferred with MIME type text/html actually response is sent in html form instead of jsKristeenkristel
That sets the dataType attribute on the ajax request, not the contentType. This results in the changing the Accepts header to json for the request. However, the Content-Type will remain unchanged.Abdel
H
7

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

JQuery UJS docs

Hanlon answered 1/8, 2017 at 0:29 Comment(1)
That's a bit heavy @DavyM. He was just trying to help and actually helped me with his link to the UJS docs.Bequest

© 2022 - 2024 — McMap. All rights reserved.