Creating a Custom Rails Route - ruby-on-rails

I am attempting to create a custom route in rails and am not sure if I am going about it in the right way. Firstly I have a RESTful resource for stashes that redirects to mystash as the controller:
map.resources :stashes, :as => 'mystash'
site.com/mystash goes to :controller => 'stashes', :action => 'show'
Which is what I want. Now is where it gets somewhat confusing. I would like to be able to add conditional params to this route. Ultimately I would like to have a route that looks like this:
site.com/mystash/zoomout/new/quiz_on/
I have places this in routes:
map.connect 'mystash/:zoom/:nav_option/:quiz',
:controller => 'stashes',
:action => 'show'
map.connect 'mystash/:zoom/:nav_option',
:controller => 'stashes',
:action => 'show'
map.connect 'mystash/:zoom',
:controller => 'stashes',
:action => 'show'
map.connect 'mystash',
:controller => 'stashes',
:action => 'show'
My routes have ended up looking like this in the browser:
site.com//mystash/zoomin?nav_option=New&quiz=quizon
and this is what one of my links looks like:
<%= link_to "In", stash_path("zoomin", :nav_option => #nav_option, :quiz => #quiz) %>
Any help is appreciated, I am pretty new to custom routes!

You should be giving these routes different names instead of the default, or you should be specifying your route with a hash and not a X_path call. For instance:
map.stash_zoom_nav_quiz 'mystash/:zoom/:nav_option/:quiz',
:controller => 'stashes',
:action => 'show'
map.stash_zoom_nav 'mystash/:zoom/:nav_option',
:controller => 'stashes',
:action => 'show'
Keep in mind that when you declare a named route, the parameters in the path must be specified in the X_path call with no omissions, and not as a hash.
link_to('Foo', stash_zoom_nav_quiz_path(#zoom, #nav_option, #quiz))
link_to('Bar', stash_zoom_nav_path(#zoom, #nav_option))
The alternative is to not bother with named routes and let the routing engine figure it out on its own:
link_to('Foo', :controller => 'stashes', :action => 'show', :zoom => #zoom, :nav_option => #nav_option, :quiz => #quiz)
If you're uncertain what routes are defined, or how to call them, always inspect the output of "rake routes" very carefully. You can also write functional tests for routes with the assert_routing method.

Related

adding and accessing controllers in ruby on rails

If I have a controller, how do I access it via URL with newly added methods?
Reason I am confused is because I have a route,
map.connect 'assignments/:external_id.:format', :controller => "assignments", :action => "show", :external_id => /\d{6}/
It seems that I can't access any other method within the assignments controller because if i do
mysite.com/assignments/other_method
It'll assume that other_method is an ID I'm passing into the show controller, as specified in the route entry above.
Edit:
I added this to the top:
map.connect 'assignments/send/', :controller => "assignments", :action => "send"
and am now getting this error:
ArgumentError in AssignmentsController#show
The route for assignments/send is the first declration for any of the assignments controller
Your routing table should have it in this order
map.connect 'assignments/:external_id.:format', :controller => "assignments", :action => "show", :external_id => /\d{6}/
map.connect 'assignments/send/', :controller => "assignments", :action => "send"
to end with
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
as your most general case.
Just specify the right route pattern for that second case and make sure you keep in mind that the mappings are evaluated from top to bottom (first match gets executed).

will_paginate route only works on page > 1

I have the following routes defined:
map.resources :categories, :has_many => :downloads
map.resources :downloads, :member => {:go => :get}, :collection => {:tag => :get}
map.connect '/downlods/page/:page', :controller => 'downloads', :action => 'index'
map.connect '/categories/:category_id/downloads/page/:page', :controller => 'downloads', :action => 'index'
For some reason, the first page that the will_paginate helper is called on causes links with ?page=2 to be rendered, while subsequent pages have links with /downloads/page/2. Do you know what might be causing this?
If you simply declare a route with map.connect, it can be hit and miss as to how it's routed if you do something like:
link_to("Next", :page => 2)
What you might want to do is name the route and then use it that way:
map.downloads_paginated '/downloads/page/:page', :controller => 'downloads', :action => 'index'
Then you use the route by name:
link_to("Next", downloads_paginated_path(2))
These are much more reliable.
As a note, you have '/downlods' in your path instead of '/downloads' but I'm not sure that'd be causing the trouble described.

Restricting ActionController/ActiveResource's map.resources routing

I have a resource exposed with two actions ONLY ('name' and 'number') and I would like to have a RESTful interface like:
resource/name/1
resource/number/ABC
but with the default
map.resources :controller_name
this doesn't work. How can I add these 2 custom actions? (total n00b here)
Thanks for any feedback!
You can't do this with a resource. You need to map a custom (named) route.
map.connect 'resource/:id/name', :controller => 'resources', :action => 'name'
map.connect 'resource/:id/number', :controller => 'resources', :action => 'number'
# the same but with named routes
map.name_resource 'resource/:id/name', :controller => 'resources', :action => 'name'
map.number_resource 'resource/:id/number', :controller => 'resources', :action => 'number'

Rails will_paginate routing caching duplicate pages

I use the will_paginate plug-in.
In oder to generate routes that I can cache ( /posts/index/2 instead of /posts?page=2) I added the following to my routes.rb:
map.connect '/posts/index/1', :controller => 'redirect', :url => '/posts/'
map.connect 'posts/index/:page',
:controller => 'posts',
:action => 'index',
:requirements => {:page => /\d+/ },
:page => nil
The first line redirects /posts/index/1 to /posts/ using a redirect controller, to avoid having a duplicate page.
Is there something wrong with the way I set up the 'posts/index/:page' rule?
I thought adding :requirements => {:page => /\d+/ } would ensure that /post/index/ without a :page parameter should not work, but /posts/index.html is getting cached.
How can I redirect /posts/index/ to /posts/ to avoid having both /posts.html and /posts/index.html ?
Thanks
UPDATE
I simply added
map.connect '/posts/index/', :controller => 'redirect', :url => '/posts/'
And I'm not getting duplicate pages anymore.
However, I still don't uderstand why I was getting /posts/index.html. Any explanations or suggestions on how to make this rule more succinct are welcome ;)!
map.connect '/posts/index/1', :controller => 'redirect', :url => '/posts/'
map.connect '/posts/index/', :controller => 'redirect', :url => '/posts/'
map.connect 'posts/index/:page',
:controller => 'posts',
:action => 'index',
:requirements => {:page => /\d+/ },
:page => nil
Here I found possible answer to your question.
I think that adding :page => nil can override previous condition. So maybe when you remove this part, it will work as you expected.

Rails: How can I configure to routes.rb for /:id?

I am working on my personal site with RoR.
I searched and read books. But I cannot figure out.
How Can I configure routes.rb for xxxxx.com/:id?
For example:
twitpic.com's image url or short url is "http://twitpic.com/11u1cy".
map.connect ':id', :controller => :your_controller, :action => :show
I'm assuming what you mean is that you want a URL like http://example.com/123 to load http://example.com/mymodel/123. If that is the case, put this at the end of your routes:
map.mymodel_id '/:id', :controller => 'mymodels', :action => 'show', :requirements => { :id => /\d+/}

Resources