Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails routing: format constraints when none is specified

For Reasons™, I want to have one controller handle html requests and another handle json api requests.

I've got this in my routes:

scope module: :api, as: :api do
  constraints format: :json do
    resources :users
  end
end
constraints format: :html do
  resources :users
end

This works great when the url sports a suffix: /users.json goes through my Api::UsersController à la api_users_path; /users.html goes through my UsersController à la users_path.

However this does not behave as expected when there is no suffix in the url. Implementing the constraints as lambda show things go wrong:

#=> visiting /users

scope module: :api, as: :api do
  constraints ->(request){ puts "In api: #{request.format}"; request.format == :json } do
    resources :users
  end
end
constraints ->(request){ puts "In html: #{request.format}"; request.format == :html } do
  resources :users
end

#=> In api: text/html
#=> (request.format == :json) => false

and yet it ends up in the api controller.

No fiddling with custom constraint classes or lambdas or anything prevents rails from selecting the first route defined if none of the constraints match.

I can't find a way to write a constraint that catches when the url lacks a suffix, and I don't feel as if I should have to–request.format == :html reports true when I'm navigating to /users. Why isn't the second constraint catching that?

Also, while I could "fix" this by changing the order of these two, I'd much rather know why my constraints aren't working right.

Does anyone know how to enforce these constraints differently to effectively switch on whatever the format is, not just the url suffix, or have an explicit constraint that accommodates no format suffix?

like image 283
Chris Keele Avatar asked Oct 11 '13 19:10

Chris Keele


1 Answers

I don't think you need the second constraints block (the one for :html). I think this should do what you want:

scope module: :api, as: :api do
  constraints format: :json do
    resources :users
  end
end

resources :users
like image 186
Jeremy Green Avatar answered Nov 03 '22 00:11

Jeremy Green