Generating routes with polymorphic_url in rails3 - ruby-on-rails-3

I've got some problems with generating routes with polymorphic_url
Here is a part of my route.rb file :
scope path: '/my-account', controller: 'customers/base', as: :customer do
...
resources :addresses, path: 'my-addresses'
...
end
rakes routes | grep addresses give me exactly the route i want :
customer_addresses GET /:locale/my-account/my-addresses(.:format)
Now, if i use
send('customer_addresses_path)
in a link_to, all work fine.
But if i'm not able to generate the same url with polymorphic url :
app.polymorphic_path([:customer,:addresses])
#ActionController::RoutingError: No route matches {:controller=>"addresses"}
app.polymorphic_path([Customer,:addresses])
#"/Customer/my-account/my-addresses" Not the same url :'(
app.polymorphic_path([Customer.first,:addresses])
#"/1/my-account/my-addresses" Not the same url :'(
Is there a way to use polymorphic_url to generate my url?

Asking a question is a good way to reflect on it.
Solution here:
app.polymorphic_path([:customer,:addresses], locale: :en)

Related

Matching same route / different HTTP verb to different controller method in Rails

I’ve got a Rails 3 app where instead of the default destruction mapping:
modelname DELETE /modelname/:id modelname#destroy
I would like a dedicated route with a GET ‘fallback’ so that users without Javascript are sent to a confirmation page:
delete_modelname DELETE /modelname/:id/delete modelname#destroy
delete_modelname GET /modelname/:id/delete modelname#confirm_destruction
I can get the above output in rake routes with the following declaration:
resources :modelname, except: [:destroy] do
member {
get 'delete', to: 'confirm_destruction'
delete 'destroy', as: 'delete'
}
end
However, one of the routes does not match, and it seems to be order-dependent, i.e. whichever is defined first then fails to match in testing. I notice that the default ‘overloaded’ routes Rails generates look a bit different in rake routes:
modelnames GET /modelname/:id/delete modelname#index
POST /modelname/:id/delete modelname#create
The route name is not repeated, and a link to create will become a link to index outside a form or a Javascript-enabled request.
It seems I’ve defined two entirely separate routes sharing the same name, rather than overloaded the path as I intended.
What am I missing? Is there any way to get the effect I’m looking for?
Things I’ve tried
Since it appeared to be the route name which was clashing, I tried this:
member {
get 'delete', to: 'confirm_destruction'
delete 'destroy', path: 'delete'
}
Changing as: to path: so that the route name would not be affected, but the paths would match. This works! The following routes are generated:
delete_modelname GET /modelname/:id/delete modelname#confirm_destruction
modelname DELETE /modelname/:id/delete modelname#destroy
This gives the effect I’m after, but unfortunately the modelname DELETE route masks the default modelname PUT route for updates.
Okay, so there is a way to do this, but it’s not quite as elegant as I’d hoped. I’m very open to a better answer if anyone has one.
resources :modelname, except: [:destroy] do
member {
get 'delete', to: 'confirm_destruction'
delete 'destroy', as: 'destroy', path: 'delete'
}
end
It works because these two new routes have unique names for using in views – delete_modelname_path and destroy_modelname_path – but if Javascript is disabled, the destroy_modelname path is still /modelnames/:id/delete, which comes in as a GET request and Rails matches it to the delete_modelname route (i.e. the confirmation page).

Writing a rails route that doesn't accept get query params

I want to match a specific route but not that route with any get query params.
Lets say I have a route like this:
get '/home', to: 'home#home
This works great for /home but how to I 404 /home?foo=bar?
If ?foo=bar makes no sense in your app it will have no effect at all.
Visiting /home?foo=bar will end seeing /home. This is quite a convention. Why do you need 404?
You can do this with an advanced constraint.
http://guides.rubyonrails.org/routing.html#advanced-constraints
class NoQueryParamsConstraint
def matches?(request)
request.query_parameters.blank?
end
end
get "/home", to: 'home#home', constraints: NoQueryParamsConstraint.new

Rails 3 Routes - prepend all url paths with set string

I've been asked to change the routes on a Rails project such that the routes will only respond to requests where the app name (or other arbitrary string) is the first string after the domain name, e.g.
www.thething.com/appname/users/sign_in instead of www.thething.com/users/sign_in
www.thething.com/appname instead of www.thething.com
www.thething.com/appname/search instead of www.thething.com/search
I've suggested using a subdomain appname.thething.com instead, but the client is quite specific about wanting the URL in the above format.
www.thething.com will be a splash page which will contain a link to www.thething.com/appname, with the intention of adding additional apps/pages in future with new folder names.
Is there an easy way of modifying the routes file so that all routes will get the .../appname prepended to all resources and routes, while being after the domain?
One option is wrap all existing routes in: namespace :appname do ... end, like so:
# config/routes.rb
Appname::Application.routes.draw do
namespace :appname do
# existing routes go here
end
end
I'm not sure if this is the most elegant solution, but it will prepend /appname to all the routes.

Missing routes in rails after using resource keyword

Not sure what the issue is here, but I have a basic line in my routes.rb:
resource :videos
But I don't see all the paths. Namely:
GET /videos/:id
I only see the following when running "rake routes":
videos POST /videos(.:format) videos#create
new_videos GET /videos/new(.:format) videos#new
edit_videos GET /videos/edit(.:format) videos#edit
GET /videos(.:format) videos#show
PUT /videos(.:format) videos#update
DELETE /videos(.:format) videos#destroy
What am I missing? Thanks!
You make videos a singular resource, but videos is a collection so you have to do :
resources :videos
http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
Change your line to resources :videos, and the missing route will magically appear

Rails 3 routes for page

I have a page_controller with a few actions (dashboard, rules, contact). Each has a corresponding view. I don't know how to route it in Rails 3.
match 'page/:action' => 'page#:action'
The above doesn't work - what I would like is named routes like: page_path(:dashboard) or page_dashboard_path.
Any ideas?
Jacob
You will have to write
get 'page/dashboard'
get 'page/rules'
get 'page/contact'
That will generate the correct named routes.
Note: you can always type rake routes to see which named routes are created.
For more info: see documentation.