在Rails API中使用render而不是respond_with / to之间的区别是什么?

时间:2015-07-13 08:01:40

标签: ruby-on-rails rails-api

我正在构建一个简单的rails教程,介绍如何为一些学生构建API,我正在构建它而没有respond_to和respond_with,因为我只是想看看我是否可以在不使用gem的情况下构建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与respond_with之间的区别是什么?我找不到任何答案。有没有我做错的事情?为什么有两种方法来创建API(respond_to / respond_with AND这种方式?)

-Jeff

3 个答案:

答案 0 :(得分:14)

  • render是Rails的一部分,它只会以您说的任何格式呈现您所说的任何内容。通常是视图,可能是字符串,可能是文件。

    一个非常低级的函数,可以呈现你所说的每个约定做出一些假设,比如在哪里查找视图。

  • respond_to是一种micro-DSL ,可让您对所请求的不同格式做出不同的响应。

    予。即在|format|调用format.json的块中,需要一个将在JSON请求时执行的块,否则将是无操作(无操作)。此外,如果respond_to没有执行任何阻止,它将使用通用406 Not Acceptable响应(服务器无法以客户端可接受的任何格式进行响应)。

    虽然可以执行if request.json?,但它不太可读,需要明确指定何时回复406。

  • respond_with ,以前是Rails的一部分,现在(自4.2起)a separate gem responders(对于reason),需要对象并使用它来构造一个响应(做出很多假设,所有这些都可以在控制器声明中给出)。

    在典型的用例(即一些API)中,它使代码更短。在不太常见的用例中,它可以根据您的需求进行定制。在极不寻常的使用案例中,这是没用的。

我可能过分简化了事情,这是一般概述。

答案 1 :(得分:3)

有两件事:){} renderrespond_to

渲染用于创建完整响应并将其发送回浏览器。 因此render用于respond_to,以使您的操作对每个调用都非常敏感,无论是js / ajax调用,整页加载(html),json(显示自动搜索下拉,令牌)还是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而不是{{ {1}}

希望帮助

答案 2 :(得分:0)

我认为答案是render只允许我回复JSON,而如果我使用respond_torespond_with,我可以回复的方式不止一种吗?这就是全部吗?