Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: 'Could not find table' in a many-to-many relationship

I have two tables set up in a many-to-many relationship: Incidents and Users. When a user is logged in, and they view the /incidents page (the index), I want to display all the incidents they are associated with. Unfortunately, the following error occurs:

Could not find table 'incidents_users'

It seems rails is looking for the table 'incidents_users', when I actually created the table 'users_incidents'. 'users_incidents' simply holds the user_id and incident_id.

Am I missing something obvious? I'm relatively new to rails, so the problem could be something simple that I've overlooked.

Here is the relevant section of the incidents_controller.rb

# GET /incidents
# GET /incidents.xml
def index
  @incidents = current_user.incidents

  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @incidents }
  end
end

Here is the relevant section of the index.html.erb

<% for incident in @incidents %>
  <tr>
    <td><%=h incident.other_id %></td>
    <td><%=h incident.title %></td>
    <td><%= link_to 'Show', [@customer, incident] %></td>
    <td><%= link_to 'Edit', edit_customer_incident_path(@customer, incident) %></td>
    <td><%= link_to 'Destroy', [@customer, incident], :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>

Thanks! Please let me know if more information would be helpful.

like image 593
Magicked Avatar asked Apr 22 '10 13:04

Magicked


1 Answers

Your join table has to be called incidents_users because the Rails' convention when using a has_and_belongs_to_many association is that the table name is derived from the lexical order of the class names of the models that comprise the association.

From the documentation:

So a join between Developer and Project will give the default join table name of "developers_projects" because "D" outranks "P". Note that this precedence is calculated using the < operator for String. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers".

Note that the table name can be overridden using the :join_table option when specifying the association, so:

class Incident < ActiveRecord::Base
  has_and_belongs_to_many :users, :join_table => 'users_incidents'
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :incidents, :join_table => 'users_incidents'
end

—It's generally best just to go with the Rails' conventions though, unless you've a particular reason that's preventing you.

like image 156
John Topley Avatar answered Sep 23 '22 02:09

John Topley