Rails respond_with : 어떻게 작동합니까?


128

respond_withRails 3에서 메소드가 얼마나 멋진 지에 대해 여기저기서 읽었 지만 Rails API 또는 소스를 검색하여 참조를 찾을 수도 없습니다. 누구나 어떻게 작동하는지 (어떤 옵션을 사용할 수 있는지 등) 설명하거나 실제로 구현 된 장소를 알려 주어 코드를 직접 읽을 수 있습니까?

답변:


128

Rails 4.2 이상 업데이트

#respond_with::respond_to( NB 클래스 메소드가) 없습니다 더 이상 레일의 일부 . 이들은 Rails 4.2 부터 타사 응답자 gem으로 마이그레이션되었습니다 ( 릴리스 노트 / 커밋 날짜 : 2014 년 8 월). 응답기는 기본적으로 Rails에 포함되어 있지 않지만 Devise의 종속성이므로 많은 Rails 애플리케이션에서 사용할 수 있습니다.

그러나 #respond_to 인스턴스 메소드여전히 Rails의 일부입니다 (이 글을 쓰는 시점의 5.2rc1).

작동 방식 을 ActionController::MimeResponds설명하는 공식 Rails API 설명서 #respond_to. 원래 레일 가이드 문서에 대한 코멘트 #respond_with::respond_to여전히에서 찾을 수 있습니다 응답자의 보석 소스 코드 .


원래 답변

응답자 코드는 클래스와 모듈을 기반으로합니다. 상속받은 클래스 인 ActionController :: Base에 포함 된 MimeResponds . 그런 다음 respond_with를 사용할 때 기본 동작을 제공하는 ActionController :: Responder 가 있습니다.ApplicationController


기본적으로 응답에서 레일이 제공하는 유일한 동작은 이름과 동작이 일치하는 템플릿을 렌더링하려는 암시 적 시도입니다. 그 이상의 작업에는 작업 내에서 더 많은 지침이 필요하거나 여러 형식 응답을 처리하기 위해 블록으로 사용자 정의 respond_to 호출이 필요합니다.

대부분의 컨트롤러는 상당히 일반적인 사용자 정의 패턴을 사용하므로 응답자는 더 많은 기본 동작을 도입하여 추가적인 추상화 수준을 제공합니다. 특정 형식에 대해 to_xml / to_json을 호출하는 작업을 읽고 성공적인 뮤 테이터 작업에 대한 리디렉션뿐만 아니라 동일하게 제공하는 뮤 테이터 작업을 읽습니다.


미묘한 조정에서 동작을 완전히 재정의하거나 확장하는 것에 이르기까지 응답자가 동작하는 방식을 사용자 지정할 수있는 몇 가지 기회가 있습니다.

수업 레벨 : respond_to

여기서 응답자가 처리해야하는 형식을 지정합니다. 적용 할 조치에 따라 형식을 사용자 정의 할 수 있습니다. 각 형식은 별도의 호출로 지정할 수 있으므로 각 형식에 대한 작업을 완전히 사용자 지정할 수 있습니다.

# Responds to html and json on all actions
respond_to :html, :json

# Responds to html and json on index and show actions only.
respond_to :html, :json, :only => [:index,:show]

# Responds to html for everything except show, and json only for index, create and update
respond_to :html, :except => [:show]
respond_to :json, :only => [:index, :create, :update]

수업 레벨 : responder

응답자를 보유하는 클래스 속성입니다. 이것은 호출에 응답하는 모든 것이 될 수 있으므로 proc / lambda 또는 호출에 응답하는 클래스를 사용할 수 있습니다. 다른 대안은 하나 이상의 모듈을 기존 응답기에 혼합하여 기존 메소드를 오버로드하여 기본 동작을 보강하는 것입니다.

class SomeController < ApplicationController
  respond_to :json

  self.responder = proc do |controller, resources, options|
    resource = resources.last
    request = controller.request
    if request.get?
      controller.render json: resource
    elsif request.post? or request.put?
      if resource.errors.any?
        render json: {:status => 'failed', :errors => resource.errors}
      else
        render json: {:status => 'created', :object => resource}
      end
    end
  end
end

흥미로운 엣지 유스 케이스가 있지만 모듈을 기본 응답기로 확장하거나 믹싱하는 것이 더 일반적인 패턴 일 가능성이 큽니다. 어쨌든 관련 응답은 from respond_with에서 전달되는 자원 및 옵션입니다.

인스턴스 레벨 : respond_with

여기의 옵션은 컨트롤러에서 render 또는 redirect_to로 전달되는 옵션이지만 성공 시나리오에만 포함됩니다. GET 작업의 경우 렌더 호출이되고 다른 작업의 경우 리디렉션 옵션이됩니다. 아마도 이들 중 가장 유용한 :location옵션은 response_with의 인수가 올바른 URL을 작성하기에 충분하지 않은 경우 경로 재 지정 경로를 대체하는 데 사용할 수있는 옵션입니다.

# These two are essentially equal
respond_with(:admin, @user, @post)
respond_with(@post, :location => admin_user_post(@user, @post)

# Respond with a 201 instead of a 200 HTTP status code, and also
# redirect to the collection path instead of the resource path
respond_with(@post, :status => :created, :location => posts_path)

# Note that if you want to pass a URL with a query string
# then the location option would be needed.
# /users?scope=active
respond_with(@user, :location => users_path(:scope => 'active'))

대안으로, 응답자 gem은 일부 기본 동작을 재정의하기위한 일부 모듈을 제공 할뿐만 아니라 기본 응답자를 확장하는 익명 클래스로 기본 응답자를 대체하고 사용자 정의 모듈을이 클래스로 혼합하기위한 클래스 레벨 메소드를 제공합니다. 가장 유용한 플래시 응답기는 기본 플래시 세트를 제공하여 기본적으로 I18n 시스템에 사용자 정의를 위임 config/locales/en.yml합니다.

이전 프로젝트에서 사용한 사용자 정의 응답자의 예로는 리소스를 자동으로 장식 한 응답자를 포함하고 페이지 제목을 쉽게 사용자 정의하거나 재정의하기위한 인터페이스가있는 기본 페이지 제목 세트를 제공했습니다.


1
나는 (클래스 본문에서) 무슨 뜻 생각 self.responder =대로 responder =현지에 할당 할
horseyguy

감사합니다! location옵션의 존재는 내가 필요한 정보였습니다!
JellicleCat

1
그 설명이 여전히 Rails 4/5와 관련이 있습니까? respond_with더 이상 사용되지 않을 것이라고 들었지만 그 이유를 알 수는 없습니다.
Arnlen

1
@Arnlen, respond_with는 별도의 보석 ' 응답자 ' 로 추출되었습니다
Nick Roz

플래시 config/locales/en.yml가 작동하려면 responders :flash컨트롤러 상단에 있어야 합니다.
bjnord
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.