Jack Franklin
Jack Franklin

Reputation: 3765

Using Ruby on Rails link_to to link to controller action

I'd just started toying around with Ruby on Rails and had come across an issue with linking to another action in a controller from a particular view. I am almost certain it's an issue (or lack of code) in my routes.rb file, but I think I'm misunderstanding exactly how this file works & what I have to do. I've got a solution but pretty sure it's not the "best way" to do it.

I have one controller called home with two actions, index (which is the default) and newbill. Inside index.html.erb I have:

<h1>Home View</h1>
<%= link_to "new", :controller => "home", :action => "newbill" %>

However I was getting a routing error:

No route matches {:controller=>"home", :action=>"newbill"}

Doing rake routes gives me the following:

root  / {:controller=>"home", :action=>"index"}

I then (following some Googling) added this code to routes.rb

match 'home/newbill' => 'home#newbill', :as => :newbill

And then in my index.html.erb I've got this:

<%= link_to "Name", newbill_path %>

And now this works as expected. My questions however are:

  1. Why does this work? What exactly is going on behind the scenes?
  2. Surely this is not the best way to do it? Adding another match 'home/newbill'... for every controller / action I want to link to seems a rubbish way of doing things.

I really like Ruby, but struggling a bit with this aspect of Rails...routing in general is messing up my head a bit I think!

Any help is much appreciated :D

Thanks,

Jack

Upvotes: 13

Views: 40538

Answers (3)

sameera207
sameera207

Reputation: 16619

I guess the first time your code didn't work because your home controller is defined as a resource.

If you define a controller as a resource in routes.rb file it will support only 7 standard methods (according to REST architecture):

index
new
create
show
edit
update
destroy

If you need any more custom routes you should add them manually, say in your case 'newbill', may go as:

resources :home do
    collection do
      get :newbill
    end
end

But as per my understanding, your newbill method should go to bills controllers new, method not in the home controller.

You are right, Rails routes are little bit confusing (at least for me), but once you understand you can do lots of cool stuff.

Read here for the Rails official routes documentation:

http://guides.rubyonrails.org/routing.html.

Upvotes: 8

Scott Radcliff
Scott Radcliff

Reputation: 1541

This works becuase rails filters every request through the router looking for a match. This enables you to define custom routes such as domain.com/post when the path is actually blog#post. Prior to rails 3, a catch-all route was the last route in the routes file. This allowed you to define a controller and action and it would just work. I'm on my iPad and not near any projects, so I can't verify it, but I think that route is still there in rails 3.1, it just needs to be umcommented.

Upvotes: 0

Brett Bender
Brett Bender

Reputation: 19738

You should check out the Rails Routing guide. A read through will help you understand what is going on behind the scenes.

Upvotes: 6

Related Questions