Search code examples
ruby-on-railsroutesruby-on-rails-5

Overuse route customizations - customize_count (Rails 5)


I am using the rails_best_practices gem which tells me i have an error:

overuse route customizations (customize_count > 8)

  resources :stores do
    collection do
      get :api
    end
    member do
      get :printer
      get :delete
      get :inventory
      delete :inventory
      get :daysheet
      get :detailed_daysheet
      get :labels
      patch :restore
      patch :print_labels
      post :daysheet
    end
  end

Resulting in these paths:

api_stores_path GET /stores/api(.:format) stores#api
printer_store_path  GET /stores/:id/printer(.:format) stores#printer
delete_store_path GET /stores/:id/delete(.:format)  stores#delete
inventory_store_path  GET /stores/:id/inventory(.:format) stores#inventory
daysheet_store_path GET /stores/:id/daysheet(.:format)  stores#daysheet
detailed_daysheet_store_path  GET /stores/:id/detailed_daysheet(.:format) stores#detailed_daysheet
labels_store_path GET /stores/:id/labels(.:format)  stores#labels
DELETE  /stores/:id/inventory(.:format) stores#inventory
restore_store_path  PATCH /stores/:id/restore(.:format) stores#restore
print_labels_store_path PATCH /stores/:id/print_labels(.:format)  stores#print_labels
POST  /stores/:id/daysheet(.:format)  stores#daysheet

After refactoring, I need it to still function as it does now with get routes such as /stores/7/inventory and /stores/18/printer

How can i compress these get routes to accomplish the same routing goals?


Solution

  • One approach would be to do:

    resources :stores do
      scope module: :stores do 
        resource  :printer,           only: [:show]
        resource  :daysheet,          only: [:show, :create]
        resource  :detailed_daysheet, only: [:show]
        resource  :inventory,         only: [:show, :destroy]
        resources :labels,            only: [:index]
        resources :print_labels,      only: [:update]
        resource  :restore,           only: [:update]
      end
      collection do
        get :api
      end
      member do
        get :delete
      end
    end  
    

    Which gives you:

              store_printer GET    /stores/:store_id/printer(.:format)              stores/printers#show
             store_daysheet GET    /stores/:store_id/daysheet(.:format)             stores/daysheets#show
                            POST   /stores/:store_id/daysheet(.:format)             stores/daysheets#create
    store_detailed_daysheet GET    /stores/:store_id/detailed_daysheet(.:format)    stores/detailed_daysheets#show
            store_inventory GET    /stores/:store_id/inventory(.:format)            stores/inventories#show
                            DELETE /stores/:store_id/inventory(.:format)            stores/inventories#destroy
               store_labels GET    /stores/:store_id/labels(.:format)               stores/labels#index
          store_print_label PATCH  /stores/:store_id/print_labels/:id(.:format)     stores/print_labels#update
                            PUT    /stores/:store_id/print_labels/:id(.:format)     stores/print_labels#update
              store_restore PATCH  /stores/:store_id/restore(.:format)              stores/restores#update
                            PUT    /stores/:store_id/restore(.:format)              stores/restores#update
                 api_stores GET    /stores/api(.:format)                            stores#api
               delete_store GET    /stores/:id/delete(.:format)                     stores#delete
                     stores GET    /stores(.:format)                                stores#index
                            POST   /stores(.:format)                                stores#create
                  new_store GET    /stores/new(.:format)                            stores#new
                 edit_store GET    /stores/:id/edit(.:format)                       stores#edit
                      store GET    /stores/:id(.:format)                            stores#show
                            PATCH  /stores/:id(.:format)                            stores#update
                            PUT    /stores/:id(.:format)                            stores#update
                            DELETE /stores/:id(.:format)                            stores#destroy
    

    Naturally, this requires that you create a number of new, nested controllers, such as Stores::Printers which will reside in app/controllers/stores/printers_controller.rb. But, you're now using standard RESTful routes, which I guess some people think is a good thing.

    Also, for your nested routes, you'll have :store_id in the params instead of id.

    That collection api and member delete still seem odd, but I'm not sure what the intention is there.