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

Ruby on rails 如何限制Rails路由文件中的资源格式,ruby-on-rails,rest,routing,content-type,Ruby On Rails,Rest,Routing,Content Type,在Rails中路由资源时,可选格式属性将自动附加到生成的路由。这是为了使所讨论的资源可以被请求为XML、HTML等。实际允许的格式通常在控制器中使用respond\u to进行描述 但在许多情况下,您只想支持HTML,在每个控制器的每个操作中编写response\u to:HTML感觉就像是一种开销。因此,在routes.rb文件中构建路由时,如果有一种方法可以限制已允许的内容类型,那就太酷了,例如 map.resources :users, :formats => :html map.reso

在Rails中路由资源时,可选格式属性将自动附加到生成的路由。这是为了使所讨论的资源可以被请求为XML、HTML等。实际允许的格式通常在控制器中使用
respond\u to
进行描述

但在许多情况下,您只想支持HTML,在每个控制器的每个操作中编写
response\u to:HTML
感觉就像是一种开销。因此,在routes.rb文件中构建路由时,如果有一种方法可以限制已允许的内容类型,那就太酷了,例如

map.resources :users, :formats => :html
map.resources :users, :formats => [:html, :xml]
map.resources :users, :formats => {:index => :html, :show => [:html, :xml]}
有没有一种方法可以通过本机或插件来实现这一点


另外,解决这个问题的通常方法是忽略问题,不要在操作中使用
respond\u
。但这实际上并没有限制允许的内容类型。相反,它只希望在views目录中为每种可能的内容类型存在一个模板。如果请求时不存在HTTP 500错误,系统将抛出HTTP 500错误。

在这两种情况下,您不想要HTTP 500错误吗?如示例的第二行所示,如果有人请求JSON而不是HTML或XML不是错误代码,则返回相应的响应?

我相信您可以这样做:

respond_to do |format|
  format.html
  format.json { render :json => @things }
  format.any { render :text => "Invalid format", :status => 403 }
end
如果用户请求html或json,它将按其应做的做,但其他任何操作都将呈现“无效格式”文本。

而不是执行以下操作:

def some_action
  ...
  respond_to do |format|
    format.html
    format.json { whatever }
    format.any { whatever  }
  end
end
只需使用:

def some_action
  ...
end
skip_before_filter :check_format, :only => ACTION_NAME

Rails将默认为查找某些_action.html.erb或请求的任何格式。如果您不定义html以外的任何视图,那么如果请求,所有其他格式都将失败。

因为Rails使用相当于通配符的方法来处理格式。“:format”要防止路由端出现问题就有点困难了

相反,在before过滤器中捕获任何非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

如果要将这些路由限制为特定格式(例如html或json),则必须将其包装在作用域中。不幸的是,在这种情况下,约束不能按预期工作

这是一个这样的块的例子

scope :format => true, :constraints => { :format => 'json' } do
  get '/bar' => "bar#index_with_json"
end
更多信息可在此处找到:

这个答案是从我以前的答案复制过来的


否,500错误表示服务器出现问题。如果内容类型不受支持,则这不是服务器错误-这是客户端错误(客户端不应请求它)。406将是正确的响应代码。请参阅“HTTP响应代码”:如果要在URL末尾标记.xml或.html,并且不支持该格式,那么应该返回404 not found。通过为每种内容类型创建URL来忽略conneg的使用,但在accept标头中没有有效的内容类型时窃取repsonse代码,这似乎有点厚颜无耻!您可能有一个观点,即使这实际上是Rails开箱即用的工作方式。不过,这不是我问题的重点。我仍然希望在一个中心位置(最好是routes文件)指定它——不管是404还是406在出错时返回,将要返回的正确代码放在一边。我认为重点是,按照惯例,它正在做它应该做的事情,你所建议的似乎是为了配置而配置。这会起作用,但我认为他想从路由中删除:格式