Форма с «remote: true» возвращает ответ 200 даже при перенаправлении - PullRequest
2 голосов
/ 04 июня 2019

У меня есть форма с remote: true, например:

<%= form_with model: @transfer, scope: :transfer, url: transfers_path, method: 'post', remote: true do |f| %>

И мой контроллер create Действие выглядит так:

def create
  @transfer = @account.transfers.build(transfer_params)
  respond_to do |format|
    if @transfer.save
      format.html { redirect_to transfers_path }
    else
      format.js
    end
  end
end

Если я отправляю форму безошибки, страница перенаправляет, как ожидалось.Однако я заметил, что сервер ответил кодом состояния 200 вместо 302. Мой журнал сервера выглядит так:

Started POST "/transfers" for ::1 at 2019-06-04 08:32:22 -0700
Processing by TransfersController#create as JS
...
Redirected to http://localhost:3000/transfers
Completed 200 OK in 1476ms (ActiveRecord: 81.2ms)

Started GET "/transfers" for ::1 at 2019-06-04 08:32:23 -0700
Processing by TransfersController#index as HTML

Просто интересно, почему это 200, а не 302?Я также понял, что это никогда не должно было работать, потому что я не мог перенаправить запрос AJAX (remote: true отправляет запрос AJAX, если я правильно понял).

Ответы на другие вопросы по SOПохоже, что redirect_to не будет работать, и мне придется использовать JS, чтобы установить расположение окна для перенаправления.Некоторые примеры ответов:

Я не понимаю, почему мойкод работает.Кто-нибудь может пролить свет на это?Я подозреваю, что rails-ujs делает некое волшебство за сценой, но я не уверен.В частности, я подозреваю, эти строки , но я не слишком хорош в JS, и я не мог разобрать большую часть этого.Я также использую Rails 5.2.1.

1 Ответ

0 голосов
/ 04 июня 2019

Прежде всего, form_with не использует remote, он использует local и по умолчанию установлен на false, то есть, как form_for с remote: true.

Во-вторых, respond_to не работает так, как вы думаете, работает. Вы не выбираете формат ответа, клиент делает.

Если клиент отправляет обычный HTTP-запрос (remote: false), то ваш create отвечает блоком после format.html. Если клиент отправляет запрос AJAX (remote: true), то create отвечает с частью format.js.

Перенаправление отсутствует, поскольку format.html { redirect_to transfers_path } никогда не запускается, поскольку вы отправляете запрос AJAX.

Проверьте ответ на вкладке network инструментов вашего браузера, чтобы узнать, что на самом деле происходит.

Также рефакторинг вашего метода:

def create
  @transfer = @account.transfers.build(transfer_params)
  saved = @transfer.save
  respond_to do |format|
    format.html do
      if saved
        redirect_to transfers_path
      else
        flash.now[:notice] = 'Error'
        render :new
      end
    end
    format.js # Create app/views/<controller>/create.js.erb and
              # update page there
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...