Rails 2, define route with a param containing slashes and dots - ruby-on-rails

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".

Related

Changing Rails 2 Routes to Rails 3 Routes

Hi I'm trying to change my routes from a rails 2 project to match the syntax in rails 3. How would I change this:
map.connect "/stylesheets/:action.css",
:controller => "stylesheets",
:format => "css"
so that the :action can be matched to an action from the stylesheets controller?
Would it be something like this?
match 'stylesheets/:action.css', :to => "stylesheets#{:action}"
Also, what is the syntax for :format in the routes for rails 3?
You're almost there with your solution. The only thing you have to change is the way you reference :action in the :to value.
match 'stylesheets/:action.css', :to => 'stylesheets#:action', :format => :css
As you can see, the syntax for :format didn't change.
I think it would be smth like:
match 'stylesheets/:action', :controller => :stylesheets, :defaults => { :format => :css }
or you can constraint your routes to .css format using :constraints => { :format => 'json' }
I recommend you to read through http://guides.rubyonrails.org/routing.html

How do I specify a default in a rails 2.3 route?

In my Rails 2.3.11 app, I want to specify that the default format for a route is :xml. According to the documentation I can do this using :defaults
map.connect '/myroute', :controller => 'mycontroller',
:action => 'myaction',
:defaults => {:format => :xml}
The documentation specifically says this should work:
You can also define other defaults in a route by supplying a hash for
the :defaults option. This even applies to parameters that are not
explicitly defined elsewhere in the route.
But if I do that, then I get this error:
/Users/simon/myproject/vendor/rails/actionpack/lib/action_controller/routing/builder.rb:107:in `assign_route_options':
format: No matching segment exists; cannot assign default (ArgumentError)
I see that a lighthouse ticket has been raised about this; a respondent notes that it works for resources but not named routes; an admin has incorrectly marked it as fixed because he's tested it on resources. Ho hum.
Elsewhere it is suggested that i do it like this:
map.connect '/myroute', :controller => 'mycontroller',
:action => 'myaction',
:format => :xml
but then if I test it
assert_generates '/myroute', :controller => 'mycontroller',
:action => 'myaction'
I get told that no route matches :controller => 'mycontroller', :action => 'myaction' - I have to put the format in by hand, so it isn't a default.
How do I specify a default in a rails 2.3 route? Do I need to get them to reopen the ticket and actually fix the bug? Is there any hope that that will happen now Rails 3 is out?
Hmmm that is pretty weird. I've used :defaults hash in a named route, and it worked for me. Can you try using a named route instead and see if it works ?
map.myroute '/myroute', :controller => 'mycontroller',
:action => 'myaction',
:defaults => {:format => :xml}

Migrating app from Rails 2 to Rails3: map.redirect

I have an app written for Rails 2 that I am trying to get running under rails3 but am failing at the first hurdle,the routes table. What I currently have is the following:
map.redirect ':shortened', :controller => 'items', :action => 'redirect', :conditions => {:method => :get}
map.shorten '', :controller => 'items', :action => 'shorten'
but I am trying to 'translate' this for rails3 - is there an equivalent to the above that would work?
many thanks in advance.
For your redirect route see here: http://guides.rubyonrails.org/routing.html#redirection
For your second route you can simply do match '/shorten/' => 'items#shorten'

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!

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.

Resources