3

In Rails you can specify defaults for a group of routes (within a namespace) like so:

Rails.application.routes.draw do
  # Other routes

  namespace :api, defaults: { format: :json } do
    resources :users
  end 
end

How can I apply defaults like this to all the routes within the application?

DanielGibbs
  • 9,910
  • 11
  • 76
  • 121
  • Not sure this is possible. But you can set the format in the `before_action` of your application controller (this is not the same though). – Yury Lebedev Nov 13 '15 at 08:52
  • That's not a bad idea actually; I already have a `before_filter` that only allows requests with the format as JSON, but I could modify this to set the format to JSON if none is set. – DanielGibbs Nov 13 '15 at 08:59

3 Answers3

5

I downvoted Yury's answer because it's inefficient.

I originally presumed (incorrectly) you wanted to set a constraint (IE only accepting JSON mime types). If this was the case, you'd benefit from this answer:

scope format: true, constraints: { format: 'json' } do
  # your routes here
end

Since you're wishing to set a default, I still believe Yury's answer to be inefficient (you'd be better setting the mime type in the middleware, not the controller).

Thus, perhaps you could use the following:

#config/routes.rb
scope format: true, defaults: { format: "json" } do
  ...
end
Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • I do only want to accept JSON requests, but using a `constraint` returns 404 for other request formats instead of 406. This looks like what I want, although I'm not familiar with `format: true`, what does it do? – DanielGibbs Nov 13 '15 at 10:14
  • Don't know - the guys on the other questions seemed to think it worked well. I think it means your scope has `format` enabled although I'd have to spend some time looking at it to know for sure – Richard Peck Nov 13 '15 at 10:15
1

Based on Yury Lebedev's answer, I've got this working using a before_action. There is a difference to the route defaults option when using this method: request.format isn't set to application/json as it is using defaults.

class ApplicationController < ActionController::Base
  before_action :default_format_json

  def default_format_json
    unless params.key?(:format)
      params[:format] = "json"
    end
  end
end
Community
  • 1
  • 1
DanielGibbs
  • 9,910
  • 11
  • 76
  • 121
0

I guess you can use the before_action globally:

class ApplicationController < ActionController::Base
  before_action :set_format

  def set_format
    return unless request.format.nil?
    request.format = :json
  end
end
Yury Lebedev
  • 3,985
  • 19
  • 26
  • I don't think this is quite right. `request.format` is a MIME type, and this would override it if it's already set. – DanielGibbs Nov 13 '15 at 09:22
  • I added a check for nil to the `set_format` function. I think the `defaults` option for routes does the same – Yury Lebedev Nov 13 '15 at 09:26
  • Even when the format isn't specified, `request.format` isn't `nil`, it's `text/html`. – DanielGibbs Nov 13 '15 at 09:29
  • I originally downvoted this, but then realized that you're trying to set a `default` not a `constraint`. This would work for a default, but not a constraint – Richard Peck Nov 13 '15 at 09:56
  • @RichPeck Daniel wrote, that he already had a `before_action`, that only allows `json` format, that's why i just added the default value – Yury Lebedev Nov 13 '15 at 10:01