1
votes

Using Rails' resources directive, I have created a set of routes for a controller (contacts). I'm now editing the default views they come with to include some of my own content. However, the link_to method is failing, telling me that I'm missing a required parameter.

No route matches {:action => 'show', :controller => 'contacts', :id => nil} missing required keys [:id]

It's obvious why this is happening - the link_to method is not being supplied with an ID, instead it's getting nil. However, the code I'm using matches the documentation for link_to.

This is the view in question:

<% @contacts.each do |contact| %>
  <tr>
    <td><%= contact.first %></td>
    <td><%= contact.last %></td>
    <td><%= contact.title %></td>
    <td><%= contact.city %></td>
    <td><%= contact.phone %></td>
    <td><%= contact.email %></td>
    <td><%= link_to 'Show', contact %></td>
    <td><%= link_to 'Edit', edit_contact_path(contact) %></td>
    <td><%= link_to 'Delete', contact.id, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
  • @contacts is a set of contacts returned from the controller. The line that sets that is:

    @contacts = Contact.select("title, first, last, city, phone, email")
                       .where("created_by" => @current_user.id)
    
  • The relevant content of the routes.rb file is simply resources :contacts.

The documentation states:

Because it relies on url_for, link_to supports both older-style controller/action/id arguments and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base your application on resources and use [...]

link_to "Profile", @profile

This appears to be what I'm using with link_to 'Show', contact.

  • Why is the ID not getting passed to link_to?
  • What can I do to remedy this?
2
Are you sure that the id value of the contact is filled ? To answer, we would need to know what is in @contacts ? Maybe there is a select clause that prevent from accessing the contact attribute ?Uelb
@Oxynum Edited in, and I think you might be right now that I look at it.ArtOfCode

2 Answers

2
votes

Change

Contact.select("title, first, last, city, phone, email")

to

Contact.select("title, first, last, city, phone, email, id")

the contact's id is nil because it isn't in the select query.

Also, although it doesn't seem to be causing problems right now, I would reccomend using an array of symbols instead of a comma-separated string, so that the sql query is more specific. For example:

Contact.select("title, first").to_sql #=> SELECT title, first FROM contacts
Contact.select(:title,:first).to_sql #=> SELECT "contacts"."title", "contacts"."first" FROM contacts

This way if you do a join with another model, it won't complain about the unspecific id in select. If you feel like you're typing too much, you can use the %i(...) syntax:

Contact.select(*%i(title first last city phone email))
1
votes

Your code seems fine.

Maybe you have an instance in the @contacts array that is not saved and therefore, has no id?

Another way to put the same (again, your code is fine) would be:

= link_to 'Show', contact_path(contact)

I would suggest posting the routes file.