Rails will_paginate routing caching duplicate pages - ruby-on-rails

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.

Related

Rails 2, define route with a param containing slashes and dots

I would like to define URLs like these ones:
/pages/VAR.1
/pages/VAR/1
So I try different configs (but none of them works):
map.page 'pages/:id', :controller => 'pages', :action => 'custom', :constraints => { :id => /[^\/]+/ }
map.page 'pages/:id', :controller => 'pages', :action => 'custom', :constraints => { :id => /(.*)+/ }
and the application redirects to 404 page. How should I do?
I'm working with ruby 1.8.7 and rais 2.3.18
Thanks in advance
Oh... my fault! I'm used with rails3, but rails2 uses "requirements" instead of "constraints".

In Ruby on Rails, how do I default to a locale when it is omitted from the url?

I have a Rails app with some internationalization, I have it setting the locale through a url parameter, like this:
/en/post/show/4 for english
/ja/post/show/4 for japanese
My routes:
ActionController::Routing::Routes.draw do |map|
map.connect "", :controller => "post", :action => "index"
map.connect "/:locale", :controller => "post", :action => "index"
map.connect "post/show/:id/:tag_title", :controller => "post", :action => "show", :requirements => {:id => /\d+/}, :path_prefix => '/:locale'
map.connect ":controller/:action/:id.:format", :requirements => {:id => /[-\d]+/}, :path_prefix => '/:locale'
map.connect ":controller/:action/:id", :requirements => {:id => /[-\d]+/}, :path_prefix => '/:locale'
map.connect ":controller/:action.:format", :path_prefix => '/:locale'
map.connect ":controller/:action", :path_prefix => '/:locale'
end
What I want is to have it so when the locale part of the url is omitted it will use the default locale. So this:
/post/show/4 is the same as
/en/post/show/4
and will set the locale to english.
What would be a good way to accomplish this? Thank you!
Find out the current language from the URL and set the I18n.locale. For example: = I18n.locale = 'en'
See also some great documentation.
I plan to implement the same approach in my app, though I have not tried it yet. I'm going to use optional route segments, like
match '(:locale/)post/show/:id' => 'posts#show'
though I think it only works in Rails 3.

Reverse rails routing: find the action name from the URL

I understand how to turn :controller, :action, :etc into a URL. I'm looking to do the reverse, how can the action that the rails router will call be found from the URL?
With Rails 3 you can do:
Rails.application.routes.recognize_path('/areas/1')
=> {:controller=>"areas", :action=>"show", :id=>"1"}
someone else might have a shorter way to do this, but if you are just evaluating a URL, then you go to the ActionController::Routing::RouteSet class
for a config.routes.rb
map.resources :sessions
the code to find is:
ActionController::Routing::Routes.recognize_path('/sessions/new', {:method => :get})
#=> {:controller => 'sessions', :action => 'new'}
Right:
ActionController::Routing::Routes.recognize_path('/sessions/1/edit', {:method => :get})
#=> {:controller => 'sessions', :action => 'edit', :id => 1}
Wrong - without the method being explicitly added, it will default match to /:controller/:action/:id:
ActionController::Routing::Routes.recognize_path('/sessions/1/edit')
#=> {:controller => 'sessions', :action => '1', :id => 'edit'}
If you are within the action and would like to know, it is quite a bit easier by calling params[:action]
everything you ever wanted to know about routeset can be found here: http://caboo.se/doc//classes/ActionController/Routing/RouteSet.html#M004878
Hope this helps!

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.

Creating a Custom Rails Route

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.

Resources