Controller can not detect ajax requests

你离开我真会死。 提交于 2019-11-29 13:59:35

You're confusing format.json|format.html with remote: true. Both are different. The presence of remote: true does not imply format.json.

format.json does not indicate that the URL was invoked via javascript. It only means that the client expects JSON output. i.e. it does not indicate where input came from, it indicates what output is required.

The general use of remote:true is, instead of reloading the page, you submit the form as an Ajax request and then show the response in a JQuery popup or something. But if you want to display the response as a JQuery popup - you need HTML output, not JSON output right?

Some people use remote: true to load HTML content in a popup. Your use case is to do remote: true but you're expecting JSON formatted data. Rails cannot make these decisions for you. It by default sends the request to /webinars and expects that you will handle the HTML response. If you really want JSON response - then customize the URL to which the Ajax request is posted:

simple_form_for @webinar, url: webinar_path(format: :json), .....

If you do the above, now the webinar controller will be called with JSON format.

Overall:

  • remote:true can be used with both format.html and format.json
  • The majority use case in a Rails application is to handle remote: true as a controller request as usual, render a partial HTML template (i.e. the response content alone without the overall page layout/navigation/etc) and send it back as HTML to be displayed in a popup
  • Most people just blanket-handle remote callbacks and display a JQuery popup. So they don't need to write individual code for each remote forms
  • So by default, Rails calls format.html for remote requests
  • If you specifically want format.json, and if you really want to handle the JSON manually on the client, change the URL accordingly. But this is not the majority use case
  • Making an Ajax request does not mean the content-type is JSON. It is a HTML request made using Javascript. e.g. In jquery $.ajax method, check these two options: accept and dataType. If you really want to send Accepts: application/json header, then you have to manually specify that when making the Ajax request (or you need to end the url with .json if its a Rails app).
  • So even if you make a normal Ajax request to /webinars, like $.ajax('/webinars', ...) - it won't go to format.json ! It will still only go to format.html. If you really want a JSON format, then you must say $.ajax('/webinars', { accepts: 'application/json' }), or you must say $.ajax('/webinars.json')

Edit: Minor clarification

It seems like you are not directly requesting a JSON formatted document in the generated form action. Perhaps one option is to set :format to json in your routes file using this technique: http://guides.rubyonrails.org/routing.html#defining-defaults

You can also define other defaults in a route by supplying a hash for the :defaults option. This even applies to parameters that you do not specify as dynamic segments. For example:

match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }

Rails would match photos/12 to the show action of PhotosController, and set params[:format] to "jpg".

I can not believe that I have lost so much time in trying to understand why the simple_form is not working as expected.

Finally, it appears that I have done everything in the right way and the issue was caused because:

AJAX can not be used for file uploads.

In order to solve my problem I simply have to add the following gem into my Gemfile and run the bundle install command:

gem 'remotipart', '~> 1.0'

Then add the following line in my application.js file:

//= require jquery.remotipart

More information about:

  1. remotipart gem
  2. How to upload multiple files using jQuery
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!