如何在Rails中设置路由的默认格式?

Sau*_*ful 42 ruby-on-rails ruby-on-rails-3

使用默认路由,request/posts /:id将映射到"show"操作:format => "html".我在show动作中使用了一些xhtml元素,除非将:content_type设置为xml,否则这些元素无法正确呈现.我目前通过渲染show.xml.erb并手动设置content_type来解决这个问题,如下所示:

format.html { render :template => "/posts/show.xml.erb", 
             :locals => {:post => @post}, :content_type => "text/xml" }
Run Code Online (Sandbox Code Playgroud)

这看起来很傻.我如何更改routes.rb以便/ posts /:id被路由format=>"xml"?谢谢.

tom*_*rte 86

请求的默认格式:

您可以使用defaults hash将给定路由的默认格式设置为xml.

例子:

# single match defaulting to XML (/plots/1 is the same as /plots/1.xml)
match 'posts/:id' => 'posts#show', :defaults => { :format => 'xml' }

# using resources, defaulting to XML (all action use XML by default)
resources :posts, :defaults => { :format => 'xml' }

# using resources and mixing with other options
resources :posts,
          :only => [:new, :create, :destroy],
          :defaults => { :format => 'xml' }
Run Code Online (Sandbox Code Playgroud)

搜索官方的Ruby on Rails路由指南总是一个好主意,它是相当深入的,并且是任何路由问题的非常好的第一站资源.

  • 您还可以设置命名空间的默认格式,例如:`namespace:user,:defaults => {:format =>'json'}` (9认同)

Jim*_*dra 22

如果您只想支持一种格式并将所有请求视为该格式,则可以使用过滤器进行更改:

before_filter :set_format

def set_format
  request.format = 'xml'
end
Run Code Online (Sandbox Code Playgroud)


Tom*_*art 10

Rails 4和5:在您的控制器中(例如,ApplicationController如果所有整个应用程序使用相同的格式)添加以下内容:

  before_action :set_default_request_format

  def set_default_request_format
    request.format = :json unless params[:format]
  end
Run Code Online (Sandbox Code Playgroud)

对于Rails 3和更早的使用before_filter而不是before_action.


Son*_*ang 6

如果要设置路由的默认格式,请使用defaults选项:

resources :posts, defaults: { format: 'xml' }
Run Code Online (Sandbox Code Playgroud)

但如果您想强制每个请求返回特定格式,请使用constraints选项:

resources :posts, constraints: lambda { |req| req.format == 'xml' }
Run Code Online (Sandbox Code Playgroud)

请参阅文档:http://edgeguides.rubyonrails.org/routing.html#request-based-constraints


zac*_*san 5

如果你使用这个,我会在 Rails 5 中发现奇怪的行为:

{ format: :json }
Run Code Online (Sandbox Code Playgroud)

在您的config/routes.rbthen 中,即使您的接受标头中未设置 JSON,它仍然会将请求强制为 JSON 请求,包括设置了选项的控制器测试as: :html。这对我来说并不是什么大问题,所以我不会深入探讨为什么会这样,但如果有人弄清楚了,请告诉我,我会更新这个答案。

  • 我也看到同样的事情。很烦人。 (2认同)