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
.
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.
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!
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With