如何限制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之外的任何视图,那么所有其他格式将在请求时失败。