program story

Rails 3 respond_to : 기본 형식?

inputbox 2020. 12. 14. 08:09
반응형

Rails 3 respond_to : 기본 형식?


Rails 2 애플리케이션을 Rails 3으로 변환하고 있습니다. 현재 다음과 같은 컨트롤러가 설정되어 있습니다.

class Api::RegionsController < ApplicationController
  respond_to :xml, :json
end

와 다음과 같은 액션 :

def index
  @regions = Region.all

  respond_with @regions  
end

구현은 매우 간단하며 api / regions, api / regions.xml 및 api / regions.json은 모두 예상대로 응답합니다. 문제는 기본적으로 api / regions가 XML을 통해 응답하기를 원한다는 것입니다. XML 응답을 기대하는 소비자가 있으며 절대적으로 필요한 경우가 아니면 모든 URL을 .xml을 포함하도록 변경하는 것을 싫어합니다.

Rails 2에서는 다음과 같이 수행 할 수 있습니다.

respond_to do |format|
  format.xml { render :xml => @region.to_xml }
  format.json { render :json => @region.to_json }
end

그러나 Rails 3에서는 XML 응답으로 기본 설정하는 방법을 찾을 수 없습니다. 어떤 아이디어?


수행하려는 작업을 이해하면 기본 리소스 형식을 XML로 설정하여 문제를 해결할 수 있습니다. 이렇게하면 사용자가 'api / regions'를 사용하여 요청을 할 수 있으며 응답 기본값은 XML입니다. 다음에서 '컨트롤러 네임 스페이스 및 라우팅'및 '기본값 정의'섹션을 살펴보십시오.

http://guides.rubyonrails.org/routing.html

route.rb에서 다음과 같이 할 수 있습니다.

namespace "api" do
  resources :regions, :defaults => { :format => 'xml' }
end

그런 다음 컨트롤러 메서드에 대해 다음 작업을 수행 할 수 있어야합니다.

class Api::RegionsController < ApplicationController
  respond_to :xml, :json

  def index 
    respond_with(@regions = Region.all)
  end
end

나는 오늘이 문제와 싸우고 before_filter있으며 귀하의 의견에서 언급 한 해결책을 결정했습니다 .

before_filter :default_format_xml

# Set format to xml unless client requires a specific format
# Works on Rails 3.0.9
def default_format_xml
  request.format = "xml" unless params[:format]
end

This solution also allows for taking into account content negotiation, which was a factor in my case. I wanted web browsers to get an HTML view but custom clients (with no Accept headers) to get JSON. This solved my problem:

before_filter :default_format_json

def default_format_json
  if(request.headers["HTTP_ACCEPT"].nil? &&
     params[:format].nil?)
    request.format = "json"
  end
end

Not what you're after but related:

def index
  @regions = Region.all
  respond_to do |format|
    format.json { render :json => @regions }
    format.any(:xml, :html) { render :xml => @regions }
  end
end

"Respond to also allows you to specify a common block for different formats by using any"


Well, as you have been noted that each format should be explicitly rendered with specific render call, you can also avoid any request with unknown or unsupported format, for my example called default, as follows:

rescue_from ActionController::UnknownFormat, with: ->{ render nothing: true }

You can simulate the unknown format call with the simple browser (exmp.firefox) line (in development mode):

http://localhost/index.default

It will call :index method of a root controller with format called as default.


An easy but ugly solution is to override html content type handling to render xml:

   respond_to :html, :xml, :json

   def index
      @regions = Region.all
      respond_with @regions do |format|
        format.html { render :xml => @regions }
      end
    end

참고URL : https://stackoverflow.com/questions/4643738/rails-3-respond-to-default-format

반응형