В чем разница между использованием рендеринга Вместо ответа с/в API Rails?

Я строю простой учебник rails о том, как создавать API для некоторых студентов, и я строю его без respond_to и respond_with, потому что я просто хочу посмотреть, могу ли я построить api без использования драгоценного камня. Это то, что у меня есть, и мои тесты проходят:

:
class Api::V1::SuyasController < ApplicationController
  def index
    render json: Suya.all
  end

  def create
    render json: Suya.create(suyas_params)
  end


  private

  def suyas_params
    params.require(:suya).permit(:meat, :spicy)
  end
end

маршруты:

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :vendors
      resources :suyas
    end
  end
end

тесты:

require 'test_helper'

class Api::V1::SuyasControllerTest < ActionController::TestCase
  test "index can get all the suyas" do
    Suya.create(meat: "beef", spicy: true)
    Suya.create(meat: "kidney", spicy: false)

    get :index
    suyas = JSON.parse(response.body)

    assert_equal "beef", suyas[0]["meat"]
    assert_equal true, suyas[0]["spicy"]
    assert_equal "kidney", suyas[1]["meat"]
    assert_equal false, suyas[1]["spicy"]
  end

  test "create can create a suya" do
    assert_difference("Suya.count", 1) do
      create_params = { suya: { meat: "beefy", spicy: true }, format: :json }

      post :create, create_params
      suya = JSON.parse(response.body)

      assert_equal "beefy", suya["meat"]
      assert_equal true, suya["spicy"]
    end
  end
end

в чем разница между использованием render vs respond_with? Я не могу найти ответов. Есть ли хоть что-то, что Я поступаю неправильно? Почему существует два способа создания API (respond_to / respond_with и этот способ?)

-Джефф

3 ответов


  • render является частью Rails и он просто делает все, что вы говорите в любом формате вы говорите. Обычно это представление, возможно строка, возможно файл.

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

  • respond_to является микро-DSL что позволяет по-разному реагировать на различные форматы запрошенный.

    т. е. в блоке |format| вызов format.json требуется блок, который будет выполняться по запросам для JSON, иначе будет no-op (без операции). Кроме того, если respond_to не выполнял никакого блока, он отвечает общим 406 неприемлемым (сервер не может отвечать в любом формате, приемлемом клиентом).

    пока это можно сделать if request.json?, это не так читаемо и необходимо явно указать, когда отвечать 406.

  • respond_with, ранее часть рельсов, теперь (с 4.2) в отдельный камень responders (для причина), берет объект и использует его для построения ответа (делая много предположений, все из них можно дать на объявлении регулятора).

    это делает код намного короче в типичных случаях использования (i. e. некоторые APIs). В не-так-типичных случаях использования его можно подгонять для того чтобы одеть ваши потребности. В очень необычных случаях это бесполезно.

я, возможно, чрезмерно упрощаю вещи, это общий обзор.


есть две вещи :)..render и respond_to.

Render используется для создания полного ответа и отправляет его обратно в браузер. Так что render используется respond_to, чтобы сделать ваше действие очень отзывчивым для каждого вызова, может ли это быть вызов js/ajax,полная загрузка страницы(html),json(чтобы показать раскрывающийся список autosearch,токены) или xml.Поэтому, если я хочу, чтобы мой метод работал и respond для каждого вызова от клиента я буду использовать блок ниже в моем действие.

  respond_to do |format|
      format.html { redirect_to(person_list_url) }
      format.js {render "show_person_details"}
      format.xml { render :xml => @people.to_xml }
      format.json { render json: @people}
    end

выше контроллер будет работать на каждом сценарии, такие как js/html/JSON и xml без получения 403 Forbidden error который мы обычно получаем, когда вызов js сделан для действия, имеющего только format.html, а не format.js

НАДЕЮСЬ, ЭТО ПОМОЖЕТ


Я думаю, что ответ заключается в том, что render позволяет мне отвечать только с помощью JSON, тогда как если я использую respond_to и respond_with, Я могу ответить более чем одним способом? И это все?