Weihang Jian
Weihang Jian

Reputation: 8715

How to set custom type/format in controller's response_to?

Environment

What I found

class ThemesController < ApplicationController
  def show
  end
end

This setting will always render the /views/themes/show.html.erb page no matter what URL extension is. For example:

http://localhost/themes/1.json
http://localhost/themes/1.xxx
http://localhost/themes/1.custom_ext
...

Encounter

I want to run render :json=>@theme when extension is json, otherwise, render the show.html.erb page, so I changed my code:

respond_to do |format|
  format.json { render :json => @theme}
  format.any {render}
end

It will correctly run render :json=>@theme when URL extension is .json, and render show.html.erb in .xml, .html, etc.

However, I got 406 Not Acceptable in .xxx, .ooo, .custom_ext, and I found it is because only supported MIME type were allowed.

Temporary solution

class ThemesController < ApplicationController
  def show
    if params[:format].present? && params[:format] == "json"
      render :json => @theme
    end
  end
end

It works fine, and when serving more then 2 formats, such as .xml, .json, .yaml, etc:

class ThemesController < ApplicationController
  def show
    case params[:format]
    when "json" then render :json => @theme
    when "xml" then render :xml => @theme
    ...
    else render
    end
  end
end

It looks clean and not worse than respond_to style :D

Question

  1. I am wondering if there is another better solution?
  2. If case statement can do every thing respond_to can do while respond_to can't, why should I use respond_to?

Upvotes: 0

Views: 436

Answers (1)

jdoe
jdoe

Reputation: 15771

Quite useful stuff, as it is usually happens, can be found in API docs.

Pay attention to the note there: Note that we used Mime::CSV for the csv mime type as it comes with Rails. For a custom renderer, you’ll need to register a mime type with Mime::Type.register.

You have to put this stuff in config/initializers/mime_types.rb. You'll find there few examples of registering non-default types.

Predefined types are here.

Upvotes: 2

Related Questions