简体   繁体   English

Rails 3 respond_to:默认格式?

[英]Rails 3 respond_to: default format?

I am converting a Rails 2 application to Rails 3. I currently have a controller set up like the following: 我正在将Rails 2应用程序转换为Rails 3.我目前有一个控制器设置如下:

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

with and an action that looks like the following: 使用和看起来如下的操作:

def index
  @regions = Region.all

  respond_with @regions  
end

The implementation is pretty straightforward, api/regions, api/regions.xml and api/regions.json all respond as you would expect. 实现非常简单,api / regions,api / regions.xml和api / regions.json都会按照您的预期做出响应。 The problem is that I want api/regions by default to respond via XML. 问题是我希望api / regions默认通过XML响应。 I have consumers that expect an XML response and I would hate to have them change all their URLs to include .xml unless absolutely necessary. 我有消费者期望XML响应,我不想让他们更改所有的URL以包含.xml,除非绝对必要。

In Rails 2 you would accomplish that by doing this: 在Rails 2中,您可以通过执行以下操作来实现:

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

But in Rails 3 I cannot find a way to default it to an XML response. 但在Rails 3中,我找不到将其默认为XML响应的方法。 Any ideas? 有任何想法吗?

If I understand what you are trying to do, you probably can solve the issue by setting the default resource format to XML. 如果我了解您要执行的操作,则可以通过将默认资源格式设置为XML来解决此问题。 This will allow your users to make requests using 'api/regions' and have the response default to XML. 这将允许您的用户使用“api / regions”发出请求,并将响应默认为XML。 Take a look at look at the 'Controller Namespaces and Routing' and the 'Defining Defaults' sections at: 请查看“Controller Namespaces and Routing”和“Defining Defaults”部分:

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

You could do something like the following in routes.rb: 您可以在routes.rb中执行以下操作:

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

Then you should be able to have the following work for your controller methods: 那么你应该可以为你的控制器方法做以下工作:

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

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

I have been fighting this issue today, and I settled for the before_filter solution you mentioned yourself in your comment: 我今天一直在讨论这个问题,我在你的评论中找到了你自己提到的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. 我希望Web浏览器能够获得HTML视图,但需要自定义客户端(没有Accept标头)来获取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: 好吧,正如您已经注意到每个格式应该使用特定的渲染调用显式呈现,您也可以避免任何具有未知或不支持格式的请求,我的示例名为default ,如下所示:

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): 您可以使用简单的浏览器(exmp.firefox)行模拟未知格式调用(在开发模式下):

http://localhost/index.default

It will call :index method of a root controller with format called as default . 它将调用:index根控制器的:index方法,其格式称为默认值

An easy but ugly solution is to override html content type handling to render xml: 一个简单但丑陋的解决方案是覆盖html内容类型处理以呈现xml:

   respond_to :html, :xml, :json

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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