Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customize Rails' Default Resourceful Route Path

TL;DR

I'd like to change the default behaviour of Rails resourceful routing, to move the create path for all resources so that it's a POST to /resources/new rather than /resources.


The Setup

Let's presume a resourceful route specified like so:

# routes.rb

resources :events


The actual routes that will be generated are:

$ rake routes

    Prefix Verb   URI Pattern                Controller#Action
    events GET    /events(.:format)          events#index
           POST   /events(.:format)          events#create
 new_event GET    /events/new(.:format)      events#new
edit_event GET    /events/:id/edit(.:format) events#edit
     event GET    /events/:id(.:format)      events#show
           PATCH  /events/:id(.:format)      events#update
           PUT    /events/:id(.:format)      events#update
           DELETE /events/:id(.:format)      events#destroy

N.B. that the create action is triggered by a POST to the /events path.


Now, if I want to change that path, I can do it "manually", on a per-resource basis:

# routes.rb

# I've placed the routes in this order, and used `as: "new_event"`,
# to avoid generating an `events_new` path helper.

post 'events/new' => 'events#create', as: "new_event"
resources :events, except: [:create]


Here are the generated routes:

$ rake routes

    Prefix Verb   URI Pattern                Controller#Action
 new_event POST   /events/new(.:format)      events#create
    events GET    /events(.:format)          events#index
           GET    /events/new(.:format)      events#new
edit_event GET    /events/:id/edit(.:format) events#edit
     event GET    /events/:id(.:format)      events#show
           PATCH  /events/:id(.:format)      events#update
           PUT    /events/:id(.:format)      events#update
           DELETE /events/:id(.:format)      events#destroy


Great! The create action is now triggered by a POST to the /events/new path, rather than the /events path.

Every other route/helper behaves exactly as before — including a GET to /events/new, and the new_event path/url helpers.


The Question

Rather than manually overriding every create action, is there a way to just change the default path used for that particular action?

Failing that, what other means could I use to change a bunch of resourceful routes, so that their create action would be moved to /new as above?

Thanks!

like image 358
ivanreese Avatar asked Jul 08 '15 12:07

ivanreese


1 Answers

You can make your life simpler by adding a module that does the overriding for you in a single place. for instance:

module MyResources
  def my_resources(resource_name, opts = {}, &block)
    opts = opts.merge(except: [:create])

    resources(resource_name, opts, &block)
    post "#{resource_name}/new" => "#{resource_name}#create", as: "new_{resource_name}"    
  end
end

ActionDispatch::Routing::Mapper.__send__ :include, MyResources

Then in your routes.rb you can do:

my_resources :events
like image 83
aschepis Avatar answered Oct 19 '22 07:10

aschepis