简体   繁体   中英

What's the difference between using render instead of respond_with/to in a Rails API?

I am building a simple rails tutorial on how to build APIs for some students and I am building it without the respond_to and respond_with because I just want to see if I can build an api without using a gem. This is what I have and my tests pass:

controller:

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

routes:

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

tests:

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

What's the difference between using render vs respond_with? I can't find any answers. Is there even something that I am doing wrong? Why are there two ways to create APIs (respond_to/respond_with AND this way?)

-Jeff

  • render is part of Rails and it just renders whatever you say in whatever format you say. Typically a view, possibly a string, possibly a file.

    A pretty low-level function that renders whatever you say making a few assumptions per conventions, like where to look for a view.

  • respond_to is a micro-DSL that allows you to respond differently to different formats being requested.

    I. e. in a block with |format| call to format.json requires a block that will be executed on requests for JSON, otherwise will be a no-op (no operation). Also, if respond_to didn't execute any block, it responds with a generic 406 Not Acceptable (server cannot respond in any format acceptable by the client).

    While it is possible to do if request.json? , it's not so readable and needs to explicitly specify when to respond with 406.

  • respond_with , formerly part of Rails, now (since 4.2) in a separate gem responders (for a reason ), takes an object and uses it to construct a response (making a lot of assumptions , all of them can be given at controller declaration).

    It makes code much shorter in typical use cases (ie some APIs). In not-so-typical use cases it can be customized to suit your needs. In highly unusual use cases it's of no use.

I may be overly simplifying things, it's a general overview.

There are two things :).. render and respond_to .

Render is used to create a full response and sends it back to the browser . So render is used in respond_to ,to make your action very responsive for every call whether it can be js/ajax call,full page load(html),json(to show autosearch dropdown,tokens) or xml.So if i want my method to work and respond to every calls from client,i will use the below block in my action.

  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

above controller will work on every scenario,such as js/html/json and xml without getting 403 Forbidden error which we get usually get when a js call is made to action having only format.html and not format.js

HOPE IT HELPS

I think the answer is that render only allows me to respond with JSON, whereas if I use respond_to and respond_with , I can respond in more than just one manner? Is that all?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM