Контроллер не может обнаружить запросы ajax

Я использую simple_form gem и генерирую форму, я указываю параметр remote: true следующим образом:

<%= simple_form_for @webinar, validate: true, remote:true do |f| %>

таким образом, выходной html для формы является следующим фрагментом:

<form accept-charset="UTF-8" action="/webinars" class="simple_form new_webinar" data-remote="true" data-validate="true" enctype="multipart/form-data" id="new_webinar" method="post" novalidate="novalidate"> ... </form>

как я проверил, используя стандартный form_for помощник добавляет Data-remote='true' в форме, когда remote: true опции. И, как вы можете видеть из сгенерированного html, когда я использую simple_form gem, есть такой атрибут тоже.

Итак, в моем контроллере у меня есть:

def create
  @webinar = Webinar.new(params[:webinar])

  respond_to do |format|
    if @webinar.save
      format.html { redirect_to @webinar, notice: 'Webinar was successfully created.' }
      format.js
      format.json { render json: @webinar, status: :created, location: @webinar }
    else
      format.html { render action: "new" }
      format.json { render json: @webinar.errors, status: :unprocessable_entity }
    end
  end
end

но, всегда .HTML-код это. Что я делаю не так?

EDIT:

я использовал logger.запрос отладки.формат, чтобы проверить, какой фактический формат запрашивает, и в файле журнала это было:

text / html

Итак, проблема должна быть в сгенерированной форме simple_form - что может быть неправильно, когда у нас есть "data-remote=true"?

3 ответов


ты путаешь format.json|format.html С remote: true. Оба разные. Присутствие remote: true не означает format.json.

format.json не означает что URL был вызван через javascript. Это означает только, что клиент ожидает выход JSON. т. е. он не указывает, откуда пришел вход, он указывает, какой выход требуется.

общее использование remote:true вместо перезагрузки страницы вы отправляете форму как Ajax запрос, а затем показать ответ во всплывающем окне JQuery или что-то еще. Но если вы хотите отобразить ответ как всплывающее окно JQuery - вам нужен вывод HTML, а не вывод JSON?

некоторые люди используют remote: true для загрузки содержимого HTML во всплывающем окне. Ваш вариант использования-сделать remote: true но вы ожидаете данные в формате JSON. Rails не может принимать эти решения за вас. Он по умолчанию отправляет запрос /webinars и ожидает, что вы будете обрабатывать HTML-ответа. Если вы действительно хотите получить ответ JSON - затем настройте URL-адрес, на который отправляется запрос Ajax:

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

если вы сделаете выше, теперь контроллер вебинара будет вызываться с форматом JSON.

в целом:

  • remote:true может использоваться с обоими format.html и format.json
  • большинство случаев использования в приложении Rails для обработки remote: true как запрос контроллера, как обычно, визуализируйте частичный шаблон HTML (т. е. только содержимое ответа без общей страницы layout / navigation / etc) и отправить его обратно в виде HTML для отображения во всплывающем окне
  • большинство людей просто одеяло обрабатывать удаленные обратные вызовы и отображать всплывающее окно JQuery. Так что не нужно писать индивидуальный код для каждой удаленной формы
  • поэтому по умолчанию Rails вызывает format.html для удаленных запросов
  • если вы специально хотите format.json, и если вы действительно хотите обработать JSON вручную на клиенте, измените URL-адрес соответственно. Но это не использование большинства дело
  • выполнение запроса Ajax не означает, что тип контента-JSON. Это HTML-запрос, сделанный с использованием Javascript. например, в в jQuery $.ajax метод, проверьте эти два варианта:accept и dataType. Если вы действительно хотите отправить Accepts: application/json заголовок, затем вы должны вручную указать, что при выполнении запроса Ajax (или вам нужно закончить url с .json если его приложение Rails).
  • поэтому, даже если вы делаете обычный запрос Ajax на /webinars, как $.ajax('/webinars', ...) - он не пойдет к format.json ! Это все равно будет только format.html. Если вы действительно хотите формат JSON, то вы должны сказать $.ajax('/webinars', { accepts: 'application/json' }), или вы должны сказать $.ajax('/webinars.json')

Edit: незначительное уточнение


похоже, что вы напрямую не запрашиваете форматированный документ JSON в сгенерированном действии формы. Возможно, один из вариантов-установить :format to json в вашем файле маршрутов, используя эту технику:http://guides.rubyonrails.org/routing.html#defining-defaults

вы также можете определить другие значения по умолчанию в маршруте, указав хэш для параметра: defaults. Это относится даже к параметрам, которые не задаются как динамические сегменты. Для пример:

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

Rails будет соответствовать photos / 12 действию show PhotosController и установить params[:format] в "jpg".


Я не могу поверить, что я потерял столько времени, пытаясь понять, почему simple_form работает не так, как ожидалось.

наконец, кажется, что я сделал все правильно, и проблема была вызвана тем, что:

AJAX не может использоваться для загрузки файлов.

чтобы решить мою проблему, я просто должен добавить следующий камень в мой Gemfile и запустить пакета установить:

gem 'remotipart', '~> 1.0'

затем добавьте следующую строку в my приложение.js:

/ / = требуется jquery.remotipart

более подробно:

  1. remotipart gem
  2. как загрузить несколько файлов с помощью jQuery