EastsideDev
EastsideDev

Reputation: 6639

Links and routes in Rails

Rails 4.1
Ruby 2.1.1

I have an application where I need to display a link to the controller show method. As far as I know, something like this will do it:

<%= link_to "Agent", agents_path(:id => agent.id), :class => "btn btn-warning" %>

But when Rails generates the link, it's this:

http://mydomain/agents?id=9

What I need is

http://mydomain/agents/9. 

When I enter this manually, I get the agents/show view. How do I get there?

In my routes, I do not have anything special for agents. Here's the relevant code from routes.rb:

resources :agents

Which means it will generate all the routes.

rake routes output:

agents GET    /agents(.:format)               agents#index
POST   /agents(.:format)                      agents#create
new_agent GET    /agents/new(.:format)        agents#new
edit_agent GET    /agents/:id/edit(.:format)  agents#edit
agent GET    /agents/:id(.:format)            agents#show
PATCH  /agents/:id(.:format)                  agents#update
PUT    /agents/:id(.:format)                  agents#update
DELETE /agents/:id(.:format)                  agents#destroy

and I did not get any errors generating the routes

Solution:

Apologies, but I was using agent_path, not agents_path. I did try agents_path at one point, as one of the things I tried. The problem is that I had two different views. In one, I was using the correct syntax:

<%= link_to "Agent", agent_path(agent.id), :class => "btn btn-warning" %>

and in the other I was using:

<%= link_to "Agent", agents_path(:id => agent.id), :class => "btn btn-warning" %>

I kept making changes to one of them, when the other was actually the one being rendered. I put the correct syntax in a partial and now it's working fine. The moral of the story is to always use partials, even when you think you don't need them.

Upvotes: 2

Views: 63

Answers (3)

Richard Peck
Richard Peck

Reputation: 76784

Routing

Something you need to consider is the resourceful nature of Rails' routing:

enter image description here

Every time you create a resources part of the Rails routing structure, you're actually telling rails to build the above routes. This is standard practice, and means you'll be able to call article_path(article.id) as default functionality.

I believe your problem stems from this idea:

<%= link_to "Agent", agents_path(:id => agent.id), :class => "btn btn-warning" %>

--

Reference

As mentioned, you're referencing agents_path (plural), when it should be agent_path (singular).

However, you're also defining the :id parameter in the route helper itself. This can just be handled by passing the object itself to the helper:

<%= link_to article.title, article_path(article.id) %>

Or, more succinctly, Rails is able to determine the path based on the resource you pass it (hence why I mentioned resourceful routes structure):

<%= link_to article.title, article %>

This will you autimagically to the show action of the articles controller.

Upvotes: 1

Benjamin Bouchet
Benjamin Bouchet

Reputation: 13181

Simply pass your record to link_to, this will automatically generate a link to its view page

= link_to 'Agent', agent
<a href="/agents/32">Agent</a>

You can do much more by using the record, example if you need a link to the edit page

= link_to 'Agent', [:edit, agent]
<a href="/agents/32/edit">Agent</a>

And so on... This technique is very useful when writing helpers that must be compatible with different models

Upvotes: 1

Bill Turner
Bill Turner

Reputation: 3697

You want agent_path instead of agents_path, and you don't need to specify the id. This will work just fine:

<%= link_to "Agent", agent_path(agent), :class => "btn btn-warning" %>

Whenever in doubt about what the routes are, you can always run:

bundle exec rake routes

And you'll be able to see all existing routes, and their naming.

Upvotes: 4

Related Questions