Jay
Jay

Reputation: 5084

Rails - Add a 'GET' sub-route to a main route

Currently I have a route called requests that may have GET/POST endpoints. But another requirement is to achieve the following format: /api/requests/sync.

I tried the following in routes.rb:

Rails.application.routes.draw do
  resources :requests do
    get "sync"
  end
end

But this gives me the following format:

/requests/:request_id/sync

How can I create a sub-route as requests/sync without having it as a sub-route of /:request_id/sync?

Upvotes: 1

Views: 705

Answers (2)

jvillian
jvillian

Reputation: 20263

Check out the guide. Specifically, collection routes. You'll do something like:

Rails.application.routes.draw do
  resources :requests do
    collection do 
      get "sync"
    end
  end
end

Which will give you requests/sync

To pick up on the sync_controller question...

Personally, not knowing much about what you're actually up to, I would keep sync as an action on the requests_controller. Something like:

class RequestsController < ApplicationController
  ...
  def sync
    ...
  end
  ...
end

While sync is not one of the standard RESTful actions, it seems more natural to me than creating a new controller. In general, but not always, I think of controllers as being noun-oriented (e.g., 'request', in your case) and actions being verb-oriented. "Sync" seems way more verb-y to me than noun-y.

You could do something along the lines of what Cyzanfar suggests. But, I would suggest you ask yourself:

  • Do you need all the standard actions for your would-be sync_controller?
  • Is there some meaningful reason to inherit from Requests::RequestsController?
  • Do you even need Requests::RequestsControler or could you just do RequestsController and then have Requests::SyncController inherit from RequestsController (which seems less tortured to me)?
  • And probably other important questions I'm not thinking about on-the-fly.

Upvotes: 3

Cyzanfar
Cyzanfar

Reputation: 7136

Here is another way to achieve this with namespacing your controllers so that you can have a distinct controller for sync and requests where the request controller will act as the parent (base) controller.

routes.rb

namespace :requests do
 resources :sync
end

requests/requests_controller.rb

class Requests::RequestsController < ApplicationController
end

requests/sync_controller.rb

class Requests::SyncController < Requests::RequestsController
end

Now you'll have the nested CRUD paths under requests

/requests/sync/new

/requests/sync/index

/requests/sync/create ...

Upvotes: 1

Related Questions