Reputation: 4320
Im a little bit confused about how both can work together format.js
and format.json
I have an ajax request and this is the controller action:
def import_contacts_submit
@new_file = ContactsFile.new(contacts_file_params)
respond_to do |format|
@new_file.save
format.js
format.json { render json: @new_file.errors, status: :unprocessable_entity } if @new_file.has_errors?
end
end
as it is, only the format.js
seems to be working, because the error callback I have in the ajax request never runs. But if I move the format.json
above the format.js
then the error callback in ajax triggers and the format.js
never runs.
Upvotes: 1
Views: 865
Reputation: 3632
Rails determines the format to take, by reading the Accept
header of the http request:
Example:
def test
f.js {
render js: "Hello World"
}
f.json {
render json: { foo: :bar }
}
end
curl localhost:3000/test -H 'Accept: application/json'
{"foo":"bar"}%
curl localhost:3000/test -H 'Accept: application/javascript'
Hello World%
Try changing the header accept
in your XHR call, e.g. when using fetch
:
fetch(url, {
headers: { 'Accept': 'application/json' },
})
Similar in jquery's.ajax or raw XHtmlRequest.
Update Rails Content negotiation:
Rails has a heuristic for determine the format. Check the Doc: https://api.rubyonrails.org/classes/ActionDispatch/Http/MimeNegotiation.html#method-i-formats
formats.first
will be taken as the "format" for the request, and the order is like this. First rule will "win":
/foo/bar.json
Upvotes: 2
Reputation: 18504
In addition to Accept
header you can explicitly state format in url:
some_path/to/import_contacts_submit.js
some_path/to/import_contacts_submit.json
Upvotes: 2