如何限制Rails路由文件中的资源格式

在Rails中路由资源时,可选的format属性会自动附加到生成的路由中。 这样可以将所讨论的资源请求为XML,HTML等。实际允许的格式通常在控制器中使用respond_to来描述。

但在许多情况下,您只想支持HTML,并且在每个控制器的每个操作中编写respond_to :html感觉都是一种开销。 因此,如果在routes.rb文件中构建路由时已经有限制允许内容类型的方法,那将是很酷的,例如

 map.resources :users, :formats => :html map.resources :users, :formats => [:html, :xml] map.resources :users, :formats => {:index => :html, :show => [:html, :xml]} 

有没有办法实现本机或通过插件?

PS解决此问题的常用方法是忽略该问题,并且不要在操作中使用respond_to 。 但这实际上并不限制允许的内容类型。 相反,它只是期望视图目录中存在每种可能的内容类型的模板。 如果在请求时不存在,系统将抛出HTTP 500错误。

如果要将这些路由限制为特定格式(例如html或json),则必须将这些路由包装在作用域中。 遗憾的是,在这种情况下,约束条件无法正常工作。

这是这样一个块的一个例子……

 scope :format => true, :constraints => { :format => 'json' } do get '/bar' => "bar#index_with_json" end 

更多信息可以在这里找到: https : //github.com/rails/rails/issues/5548

这个答案是从我之前的答案复制而来的。

Rails Routes – 限制资源的可用格式

由于Rails使用相当于通配符来处理格式“。:format”,因此在路由方面阻止事情要困难得多。

取而代之的是,在filter中捕获任何非HTML请求非常简单。 这可能是这样的一种方式:

 class ApplicationController < ActionController::Base before_filter :check_format private def check_format if request.format != Mime::HTML raise ActionController::RoutingError, "Format #{params[:format].inspect} not supported for #{request.path.inspect}" end end end 

ActionController :: RoutingErrors被处理为404错误,这是明智的。 如果您确实需要支持HTML以外的操作,请使用:

 skip_before_filter :check_format, :only => ACTION_NAME 

我相信你能做到这样的事情:

 respond_to do |format| format.html format.json { render :json => @things } format.any { render :text => "Invalid format", :status => 403 } end 

如果用户请求html或json,它将按原样执行,但其他任何内容都将呈现“无效格式”文本。

在任何一种情况下,您不希望HTTP 500错误? 就像在你的例子的第二行,如果有人请求JSON而不是HTML或XML不是错误代码返回适当的响应?

而不是做:

 def some_action ... respond_to do |format| format.html format.json { whatever } format.any { whatever } end end 

只需使用:

 def some_action ... end 

并且Rails将默认查找some_action.html.erb或请求的任何格式。 如果您没有定义除html之外的任何视图,那么所有其他格式将在请求时失败。