Ruby-on-rails Rails 3 respond_to:默认格式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4643738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:03:25  来源:igfitidea点击:

Rails 3 respond_to: default format?

ruby-on-railsruby-on-rails-3

提问by bdorry

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. The problem is that I want api/regions by default to respond via 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.

实现非常简单,api/regions、api/regions.xml 和 api/regions.json 都按您的预期响应。问题是我希望 api/regions 默认通过 XML 响应。我有消费者希望得到 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. Any ideas?

但是在 Rails 3 中,我找不到将其默认为 XML 响应的方法。有任何想法吗?

回答by Mike Clymer

If I understand what you are trying to do, you probably can solve the issue by setting the default resource format to XML. This will allow your users to make requests using 'api/regions' and have the response default to XML. Take a look at look at the 'Controller Namespaces and Routing' and the 'Defining Defaults' sections at:

如果我明白您要做什么,您可能可以通过将默认资源格式设置为 XML 来解决问题。这将允许您的用户使用“api/regions”发出请求,并将响应默认为 XML。查看“控制器命名空间和路由”和“定义默认值”部分:

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

回答by clacke

I have been fighting this issue today, and I settled for the before_filtersolution 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. This solved my problem:

该解决方案还允许考虑内容协商,这在我的案例中是一个因素。我希望 Web 浏览器获得 HTML 视图,但自定义客户端(没有 Accept 标头)获得 JSON。这解决了我的问题:

before_filter :default_format_json

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

回答by Heikki

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"

“响应还允许您使用 any 为不同格式指定一个公共块”

回答by Малъ Скрылевъ

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 :indexmethod of a root controller with format called as default.

它将调用:index根控制器的方法,格式为default

回答by buru

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