Rails 3 - Restricting formats for action in resource routes

27,444

Solution 1

I found that this seemed to work (thanks to @Pan for pointing me in the right direction):

resources :categories, :except => [:show]
resources :categories, :only => [:show], :defaults => { :format => 'json' }

The above seems to force the router into serving a format-less request, to the show action, as json by default.

Solution 2

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

Solution 3

You could do the following in your routes.rb file to make sure that only the show action is constrained to json or xml:

resources :categories, :except => [:show]
resources :categories, :only => [:show], :constraints => {:format => /(json|xml)/}

If this doesn't work you could try explicitly matching the action:

resources :categories, :except => [:show]
match 'categories/:id.:format' => 'categories#show', :constraints => {:format => /(json|xml)/}
Share:
27,444
Mike
Author by

Mike

I'm a Software Engineer working in London/remote, UK. I specialise in all things Frontend, including JavaScript, Node, CSS, HTML and React. I've also worked with Ruby and PHP.

Updated on July 17, 2020

Comments

  • Mike
    Mike almost 4 years

    I have a resource defined in my routes.

    resources :categories
    

    And I have the following in my Category controller:

      def show
        @category = Category.find(params[:id])
    
        respond_to do |format|
          format.json { render :json => @category }
          format.xml  { render :xml => @category }
        end
      end
    

    The controller action works fine for json and xml. However I do NOT want the controller to respond to html format requests. How can I only allow json and xml? This should only happen in the show action.

    What is the best way to achieve this? Also is there any good tips for DRYing up the respond_to block?

    Thanks for your help.

  • Mike
    Mike about 13 years
    Sorry, this didn't appear to work. Requesting an html page still responds.
  • Pan Thomakos
    Pan Thomakos about 13 years
    I added another more explicit alternative if the first option doesn't work for you.
  • jwarzech
    jwarzech almost 12 years
    This will still respond with the html template if the .html extension is added to the url.
  • Kamil Jopek
    Kamil Jopek over 11 years
    Thank you, this is very useful answer. Worked for me like a charm.
  • koonse
    koonse about 11 years
    this will not limit requests to those formats, see my answer below for the correct implementation
  • Pathogen
    Pathogen almost 9 years
    The reason why the first part of this answer doesn't work, is that while it constrains the format it doesn't require that it be present. koonse's answer is better.
  • Andrey Artemyev
    Andrey Artemyev about 8 years
    Only "constraints" or "defaults" doesn't work for me, this answer is right.