Почему response_to выполняет format. html вместо format. json при использовании AJAX? - PullRequest
0 голосов
/ 07 мая 2020

Я искал похожие темы, но, хотя я много читал, я все еще немного запутался в использовании блока response_to.

Я делаю запрос AJAX с помощью form_with на стороне клиента. В контроллере мое действие выглядит следующим образом:

  def create
    @role = Role.new(role_params)

    respond_to do |format|
      if @role.save
        format.html { redirect_to url_for(controller: 'roles', action: 'index') }
        format.json { render json: { :location => url_for(controller: 'roles', action: 'index') }, status: 302 }
      else
        format.html { render action: 'new' }
        format.json { render json: { :errors => @role.errors }, status: 422 }
      end
    end
  end

Я понимаю, что response_to bock состоит в том, что когда вы делаете запрос AJAX, он должен ответить, используя json, и если вы сделаете на обычный запрос он должен ответить, используя html. Это правильно?

В этом случае он всегда отвечает, используя формат. html. Я проверил, что если я сначала поставлю формат. json (выше формат. html), он действительно ответит, используя json.

Что не так или что мне не хватает?

Спасибо!

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Насколько я понимаю, response_to bock состоит в том, что когда вы делаете запрос AJAX, он должен отвечать, используя json, а если вы делаете обычный запрос, он должен отвечать, используя html. Это верно?

Не совсем. Запрос AJAX - это просто асинхронный запрос, а тип ответа должен зависеть от заголовков Content-Type и Accept-Type. Запрос запроса AJAX может фактически запрашивать любой возможный тип контента - JSON является наиболее часто используемым и, возможно, наиболее полезным типом.

Если запрос не содержит определенного типа контента c или Тип принятия Rails по умолчанию будет html, если вы не переопределите его в маршрутах:

namespace :api, defaults: { format: :json } do
  namespace :v1 do
    resources :things
  end
end

Rails U JS, который встроен в рельсы и поддерживает параметр remote: true в формах и ссылках, который фактически использует application/javascript в качестве типа содержимого по умолчанию, поскольку он позволяет писать js.erb представления и повторно использовать шаблоны рельсов без написания обработчиков ajax. Если это действительно идея хорошая, хотя это спорно, поскольку это приводит к очень сомнительных проектных решений

1014 * С Rails U JS самый простой способ установить тип контента через * атрибут * 1015:.
<%= link_to "Click Me!", "/foo", remote: true, data: { type: :json } %>
<%= form_with(model, html: { data: { type: "json" }}) %>

Если вы отправляете запрос Ajax «вручную» с помощью XMLHttpRequest, вы можете установить тип контента с помощью setRequestHeader.

xhr.setRequestHeader("Content-Type", "application/json"); 

С jQuery вы используете type: вариант для функций ajax или jQuery.getJSON.

Также правильный способ ответить на успешный запрос POST - это 201 Created.

201 Создано. Запрос был выполнен, и в результате был создан один или несколько новых ресурсов. Первичный ресурс, созданный запросом, идентифицируется либо полем заголовка Location в ответе, либо, если поле Location не получено, действующим URI запроса.

format.json { head :created, location: @role }

Вы также можете дополнительно включить созданный ресурс в теле ответа.

format.json { render json: @role, location: @role, status: :created }
1 голос
/ 07 мая 2020

form_with по умолчанию отправляет XHR (ajax) запрос, требующий, чтобы вы имели java-script template для ответа, а затем используйте format.js внутри метода ответа.

однако, если вы хотите сделать json или любые другие форматы запросов, такие как xml, вы можете передать формат в качестве параметра вспомогательному методу пути, например:

admin_roles_path(format: :json)

, или используйте параметр формата непосредственно в form_with звоните, но, поскольку вы уже используете опцию url, опция format будет опущена.

для получения дополнительной информации это - хороший пост для чтения.

...