Rails routes: collection routes keep adding "_index" to url helper? - ruby-on-rails

I'm trying to create extra paths for my checkout controller. Here are my routes:
resources :checkout do
collection do
post :add_to_cart, :to => 'checkout#add_to_cart'
put :update_shopping_cart, :to => 'checkout#update_shopping_cart'
get :billing
post :update_billing
put :update_billing
post :update_shipping
put :update_shipping
get :order_summary
post :submit_order
get :order_complete
get :clone_shipping_address
get :estimate_shipping
end
end
However, when I do a bundle exec rake routes | grep checkout, all my custom routes have an _index suffix that I don't want:
add_to_cart_checkout_index POST /checkout/add_to_cart(.:format) checkout#add_to_cart
update_shopping_cart_checkout_index PUT /checkout/update_shopping_cart(.:format) checkout#update_shopping_cart
billing_checkout_index GET /checkout/billing(.:format) checkout#billing
update_billing_checkout_index POST /checkout/update_billing(.:format) checkout#update_billing
PUT /checkout/update_billing(.:format) checkout#update_billing
update_shipping_checkout_index POST /checkout/update_shipping(.:format) checkout#update_shipping
PUT /checkout/update_shipping(.:format) checkout#update_shipping
order_summary_checkout_index GET /checkout/order_summary(.:format) checkout#order_summary
submit_order_checkout_index POST /checkout/submit_order(.:format) checkout#submit_order
order_complete_checkout_index GET /checkout/order_complete(.:format) checkout#order_complete
clone_shipping_address_checkout_index GET /checkout/clone_shipping_address(.:format) checkout#clone_shipping_address
estimate_shipping_checkout_index GET /checkout/estimate_shipping(.:format) checkout#estimate_shipping
checkout_index GET /checkout(.:format) checkout#index
POST /checkout(.:format) checkout#create
new_checkout GET /checkout/new(.:format) checkout#new
edit_checkout GET /checkout/:id/edit(.:format) checkout#edit
checkout GET /checkout/:id(.:format) checkout#show
PUT /checkout/:id(.:format) checkout#update
DELETE /checkout/:id(.:format) checkout#destroy
How would I remove that?

You have to pluralize the name of the resources:
resources :checkouts do
## your routes
end
In fact you have to use resource :checkout or resources :checkouts, depending on what you need.

Related

Change name of scaffold routes

Is there a way to change the name of the routes that my scaffold created? I made a scaffold for Cars. Currently I have resources :cars in my routes. How can I change the routes such that my url shows http://localhost:3000/transportation instead of http://localhost:3000/cars? I do not need to change the name of the entity in my schema, all I want to change are the routes associated with it. How can I go about this?
Is there no other way to achieve this but to do a get for each? Ex:
get '/transportation', to: 'cars#index', as: 'cars_index'
You can define the new route after the resources created by your scaffold to respond to your cars controller and index action, or any other other, depending on what you want to achieve.
resources :cars
get 'transportation', to: 'cars#index'
If you want to apply it for all your routes on the car scaffold, then you can pass a path option:
resources :cars, path: 'transportations'
This way the routes pointing to car won't be available and will be replaced for transportations.
You can redefine resource routes with custom URLs by passing a string of your choice along with :path option along with its route definition in routes.rb
resources :cars, :path => "transportation"
With this route definition, access to cars resources in your app will be routed to these URLs
cars GET /transportation(.:format) cars#index
POST /transportation(.:format) cars#create
new_car GET /transportation/new(.:format) cars#new
edit_car GET /transportation/:id/edit(.:format) cars#edit
car GET /transportation/:id(.:format) cars#show
PATCH /transportation/:id(.:format) cars#update
PUT /transportation/:id(.:format) cars#update
DELETE /transportation/:id(.:format) cars#destroy

Rails routes config thinks action method is an object id

I'm developing rails application and encountered such problem.
I have movies_controller.rb, where I have these actions and routes defined:
Prefix Verb URI Pattern Controller#Action
movies GET /movies(.:format) movies#index
POST /movies(.:format) movies#create
new_movie GET /movies/new(.:format) movies#new
edit_movie GET /movies/:id/edit(.:format) movies#edit
movie GET /movies/:id(.:format) movies#show
PATCH /movies/:id(.:format) movies#update
PUT /movies/:id(.:format) movies#update
DELETE /movies/:id(.:format) movies#destroy
root GET / redirect(301, /movies)
movies_by_director GET /movies/by_director(.:format) movies#by_director
But when I try to go to /movies/by_director?director="something", rails think, that I'm navigating to movies#show action with parameter :id = by_director.
What am I doing wrong?
Routes are matched in the order they are specified so make sure the route for "by_director" is defined above the resource routes for movies.
Something like this should do the trick:
get '/movies/by_director' => 'movies#by_director'
resources :movies
There are two problems in one here:
The default pattern matching for :id is loose enough that by_director is interpreted as an :id.
Routes are matched in order and GET /movies/:id appears before GET
/movies/by_director.
You can manually define GET /movies/by_director before your resources :movie as infused suggests or you could add a constraint to narrow what :ids look like:
resources :movies, constraints: { id: /\d+/ } do
#...
end
Manually ordering the routes is fine if there's just one or two of them to deal with, constraining :id is (IMO) cleaner and less error prone.

rails routing, add path name also keep old urls working

in my routes file, when i change
resources :foobar
to
resources :foobars, path: "foo-bars"
the urls become example.com/foo-bars, example.com/foo-bars/1 etc.
this is ok.
but how can i also keep the old urls, example.com/foobars, example.com/foobar/3 also working?
i know, i can hardcode it,
get "foobars", to: 'foobar#index'
get "foobar/:id", to: 'foobar#show'
...
but is there a clean way to implement this?
Define both of them
resources :foobars, path: "foo-bars"
resources :foobars, path: "foobars"
EDIT:
For custom actions instead of declaring them twice for each path like this,
resources :foobars, path: "foo-bars"
collection do
get 'bulk_new'
patch 'bulk_create'
get 'bulk_edit'
patch 'bulk_update'
end
end
resources :foobars, path: "foobars"
collection do
get 'bulk_new'
patch 'bulk_create'
get 'bulk_edit'
patch 'bulk_update'
end
end
Create common block and pass it to both resource method calls.
common_block = lambda do
collection do
get 'bulk_new'
patch 'bulk_create'
get 'bulk_edit'
patch 'bulk_update'
end
end
resources :foobars, path: "foo-bars", &common_block
resources :foobars, path: "foobars", &common_block

Can we rename a resource collection/member URL?

I have this resource in routes.rb
resources :orders, only:[] do
collection do
post :user_order_confirmation
end
end
which creates a path like this in HTML views 'orders/carrier_order_confirmation'. Can we do something that this path looks like this 'orders/user_confirmation'?
You can do
resources :orders, only:[] do
collection do
post :user_confirmation, acion: :user_order_confirmation
end
end
This will give you the exact route as you are looking for. Here is the test :
$ rake routes | grep orders
user_confirmation_orders POST /orders/user_confirmation(.:format) orders#user_confirmation {:acion=>:user_order_confirmation}
You can overwrite the conventional routes by adding the following line in your routes.rb after you set the resource routes:
get "/orders/user_confirmation" => "orders#user_confirmation", as: "user_confirmation"
To clarify, here's what each part of that means:
[Routing Method] "/[Route You want]" => "[Controller]#[Controller Method]", as: "[Custom Route Name]"
Try this
post :user_order_confirmation, as: :user_confirmation

Ruby on Rails 3: Change default controller and parameter order in routing

I have a Rails app that has a controller called domain which has a nested controller called subdomain and stats. I have defined them in routes.rb:
resources :domains do
resources :subdomains, :stats
end
I have changed the to_param of the domain and subdomain models to use the name of the domain, e.g.: the routing I get is http://site/domains/foo/subdomains/bar.
I would like to tidy it up to so that instead of using http://site/domains/foo/subdomains/bar I could access it with just http://site/foo/subdomains/bar. I have tried the following in routes.rb:
match "/:id/" => "domains#show", :as => :domain
Which works fine, but it only gives me the ability to use the path http://site/foo but for example http://site/foo/subdomains/bar doesn't. I could create match lines for every respective model and nested model but that does nothing to other helpers besides domain_url - i.e. edit_domain_url points to /domains/foo/edit/ instead of /foo/edit.
Is there a way to change the routing so that the resources generates helpers that point to the root url without the 'domains' part?
The single match in your routes creates only one route. Resource helpers create many routes at once. Luckily there are a lot of options for customisation. If you want to omit /domains/ from your paths, it's as simple as:
resources :domains, :path => "/" do
resources :subdomains, :stats
end
With the above in config/routes.rb, running rake routes says the following:
domain_subdomains GET /:domain_id/subdomains(.:format)
domain_subdomains POST /:domain_id/subdomains(.:format)
new_domain_subdomain GET /:domain_id/subdomains/new(.:format)
edit_domain_subdomain GET /:domain_id/subdomains/:id/edit(.:format)
domain_subdomain GET /:domain_id/subdomains/:id(.:format)
domain_subdomain PUT /:domain_id/subdomains/:id(.:format)
domain_subdomain DELETE /:domain_id/subdomains/:id(.:format)
domain_stats GET /:domain_id/stats(.:format)
domain_stats POST /:domain_id/stats(.:format)
new_domain_stat GET /:domain_id/stats/new(.:format)
edit_domain_stat GET /:domain_id/stats/:id/edit(.:format)
domain_stat GET /:domain_id/stats/:id(.:format)
domain_stat PUT /:domain_id/stats/:id(.:format)
domain_stat DELETE /:domain_id/stats/:id(.:format)
domains GET /(.:format)
domains POST /(.:format)
new_domain GET /new(.:format)
edit_domain GET /:id/edit(.:format)
domain GET /:id(.:format)
domain PUT /:id(.:format)
domain DELETE /:id(.:format)
Looks like all the routes you need!

Resources