Контроллер не может обнаружить запросы 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
более подробно: