Rails 3 routing - passing params from routes.rb - ruby-on-rails

In rails 2.3.5 you could do something like this inside the routes.rb file:
map.root :controller => "pages", :action => "show", :id => 3
In rails 3 I haven't found any way to pass a specific parameter (like in rails 2.3.5 with :id => 3).
I know I can handle it from the controller and have the same result (which I did), but I was wondering if there is a way to do the same thing in rails 3 from the routes.rb or has it changed because it is better practice for some reason?

Are you sure the following doesn't work?
root :to => "pages#show", :id => 3

Related

Why to add a connection in routes file when using link_to in rails 2

I was trying to accomplish the following:
<%= link_to "Log out", { :controller
=> 'users', :action => 'logout' }, :class => 'menulink2' %>
But it didn't work, it always redirected me to a show view. I had to had the following to my routes.rb:
map.connect 'users/logout',
:controller => 'users', :action =>
'logout'
Why didn't rails recognize the action I was passing ('logout') ?
That logic has to be specified somewhere. There's got to be some mapping from the hash {:controller => 'users', :action => 'logout'} to a url, and the place that's done in rails is the routes.rb file. In older versions of rails many routes.rb came with a default at the end:
map.connect ':controller(/:action/(:id(.:format)))'
Which would make it so that most any :controller, :action hash could be specified and then routed to host.url/:controller/:action.
With the more modern versions resource-based routes are heavily favored, and controllers which don't follow rails' REST conventions (i.e. having only :index,:show,:create,:new,:edit,:update,:destroy methods) generally have to have their routes explicitly specified in some way.
(Either with map.resources :users, :collection => {:get => :logout} or with map.connect( 'some_url', :controller => 'users', :action => 'logout'}))
I'm guessing, but the reason they did that is probably that the actions of a controller are really just its public methods.
It's frequently nice to have public methods in your controllers that aren't url-end-points for testing purposes.
For instance, you could have before_filters as public methods that you might want to test without having to use #controller.send(:your_before_filter_method) in your test code.
So they whitelist the resource actions, and make the others unreachable by default. Let me look through the rails changelog and see if I'm right.

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}

Rails 3 Routing problem

I convert the Rails-2 application into Rails-3. In my Rails-2 routing i have the routes like the below
Rails 2
map.connect 'example/:action/:id.:format', :controller => 'Test',:q =>'example-string'
Note: This is working well in Rails-2 application; when the url comes with /example it redirect to Test controller's index action with the parameter q="example-string"
I converted the above to support Rails-3 routes:
match 'example(/:action(/:id.(:format)))',:to => 'Test',:q=>'example-stirng'
The problem is I got the Routing Error /example not found.
How can i change the Rails-2 routes into Rails-3 routes?
You almost got it right. Should be
match 'example(/:action(/:id.(:format)))',:controller => :test, :q=>'example-stirng'
:to => "foo#bar" is a shortcut for :controller => :foo, :action => :bar

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'

Creating Twitter-style routes with Rails3

How can I make Twitter-style routes with Rails3?
I've tried the following:
match ':username', :controller => "users", :action => "show"
match ':username/:controller(/:action(/:id))', :path_prefix => '/:username'
EDIT
After some more digging through the docs, I did this and it seems to work:
scope '/:username' do
resources :clubs
end
What is the "scope" method exactly and is there an automatic way of generating link_to URLs in my views?
The following matcher will match /dhh/update/1
match ':username/update/:id' => 'updates#show'
'update#show' is new in Rails 3 and is the short version of :controller => 'updates', :action => 'show'
Try clubs_path(:username => 'bob').

Resources