reesaspieces
reesaspieces

Reputation: 1800

Should I use resource routing even for non-CRUD routes (Rails)?

Is it considered best practice to use resourceful routes in Rails whenever possible, even if the CRUD verbs don't really match the actions being performed (details follow)?

In my Rails app, I'm implementing an OAuth login system using sorcery's external module. I closely followed their official tutorial, which defines the routes for the OAuth methods like this.

# config/routes.rb
post "oauth/callback" => "oauths#callback"
get "oauth/callback" => "oauths#callback" # for use with Github, Facebook
get "oauth/:provider" => "oauths#oauth", :as => :auth_at_provider

Basically, auth_at_provider is called when the user clicks the "Login via [Provider Name]" button, and the callback is called once they log in via the external provider.

I left the routes as-is, but a teammate reviewing it suggested we use resource routing, like this for example:

resources :oauth only: [:index, :create, :show]

I guess this is technically possible, but for me the singular routes defined in the tutorial are much more intuitive and self-explanatory. So my questions are:

Upvotes: 1

Views: 1207

Answers (2)

arieljuod
arieljuod

Reputation: 15838

I wouldn't use the resource(s) helpers. The name tells you it's used for resources and oauth logic are not resources.

You could refactor the routes a little bit though

namespace :oauth do
  match :callback, via: [:get, :post]
  get ":provider", action: :oauth, as: :at_provider
end

This creates this routes:

              oauth_callback GET|POST /oauth/callback(.:format)                                                                oauth#callback
           oauth_at_provider GET      /oauth/:provider(.:format)                                                               oauth#oauth

They are basically the same routes, DRYer and without misleading "resource" wording.

*Note the little change from "auth_at_provider" to "oauth_at_provider" introduced by the namespace

Upvotes: 3

James Balazs
James Balazs

Reputation: 98

It is generally considered best practice to use resourceful routing when you're actually doing CRUD on a resource, ie:

resources :users # for creating, reading, updating, deleting users

If you'd have to create an entirely new resource and controller just for one create endpoint (for example), I don't see any harm in breaking the pattern and using non-resourceful routes, but I try to avoid doing so.

You should try to use resourceful routing with names that makes sense, to keep your routes consistent:

scope path: 'oauth' do
  resource :callback, only: [:show, :update] # use show/update instead of callback method
  resources :providers, only: [:show] # use show instead of auth_at_provider
end

So your routes would look like:

POST oauth/callback
GET  oauth/callback
GET  oauth/providers/:id

Upvotes: 3

Related Questions