How to limit the resource formats in the Rails routes file

浪子不回头ぞ 提交于 2019-12-03 06:29:51
koonse

You must wrap those routes in a scope if you want to restrict them to a specific format (e.g. html or json). Constraints unfortunately don't work as expected in this case.

This is an example of such a block...

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

More information can be found here: https://github.com/rails/rails/issues/5548

This answer is copied from my previous answer here..

Rails Routes - Limiting the available formats for a resource

Since Rails uses the equivalent of a wildcard to handle formats ".:format" it's a bit more difficult to prevent things on the route side.

Instead of this, it's pretty easy way to catch any non HTML requests in a before filter. Here's one way this might look:

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 are handled as 404 errors which is sensible. In the event that you do have an action that needs to support something other than HTML, just use:

skip_before_filter :check_format, :only => ACTION_NAME

I believe you are able to do something like this:

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

If the user requests html or json it'll do it as it should, but anything else will render the "Invalid Format" text.

In either case wouldn't you want a HTTP 500 error? Like in the second line of your example, if someone requested JSON instead of HTML or XML isn't an error code return the appropriate response?

rather than doing:

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

just use:

def some_action
  ...
end

and Rails will default to looking for some_action.html.erb or whatever format was requested. If you don't define any views other than html, then all other formats will fail if requested.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!