4

I've only created a has_and_belongs_to_many association before and it is different from has_many :through. For a has_many :through association, do I need a join table? How does the actual association work? Do I need an index? I can't find a great tutorial on this, any suggestions?

Michael Durrant
  • 84,444
  • 83
  • 284
  • 429
Matthew Berman
  • 8,025
  • 8
  • 42
  • 92

2 Answers2

7

Yes you need the join table. This shows how: http://railscasts.com/episodes/47-two-many-to-many

This may also be helpful; has_many :through questions

By the way if you need to search with condition this will help: Has many through associations with conditions

Also a great example with code of editing the nested attributes of the join table at Rails nested form with has_many :through, how to edit attributes of join model?.

All these are sorts of things you might find yourself wanting to do :)

Index are optional and also vary by db. mySQL used to only support 1 at a time. Not sure if that has changed.

Community
  • 1
  • 1
Michael Durrant
  • 84,444
  • 83
  • 284
  • 429
  • Ok cool. I watched the railscast on this. I am a little confused - did he explicitly create a join table with a migration or did the act of creating the has_many through models and then db:migrate create the join table automatically? – Matthew Berman Oct 14 '11 at 00:13
  • No tables are made unless a migration or schema file tells it to. – bricker Oct 14 '11 at 00:32
  • So, by creating the join model and then migrating...that creates the "join table" ? Or do I still need to do the rails g migration events_model_join thing? – Matthew Berman Oct 14 '11 at 00:33
  • yes run a `generate` for the model and include or add the attributes in the migration and then rake db:migration to actually create the database model. migration to create – Michael Durrant Oct 14 '11 at 01:36
  • 1
    ... the database table. An issue you might be thinking of is whereby, unless the join table is explicitly specified as an option, it is guessed using the lexical order of the class names. So a join between Developer and Project will give the default join table name of “developers_projects”. Plus the join table for habtm should not have a primary key or a model associated with it. You must manually generate the join table with a migration. – Michael Durrant Oct 14 '11 at 01:47
1

It depends on how you want to use the has_many :through relation. There are two different cases (named in the guide to relations

  1. for an n:m relation: the example in the guide is physicians have appointments with patients.
  2. for an 1:n and an additional 1:n relation: the example in the guide is 1 document has many sections and 1 section has many paragraphs.

For the first one, you need the join table, you don't need the index. For the second one, you need none of them.

mliebelt
  • 14,995
  • 7
  • 50
  • 90
  • I wouldn't say the second example doesn't need a join table. "Sections" is technically the join table between Document and Paragraphs, even though it's weird to think of that as a "join table". – bricker Oct 13 '11 at 23:41
  • All I wanted to say was depending on the usage of `has_many :through`, you will need a join table or not. If a document has many section, and each section has many paragraphs, you have created the models first independently, and have then added in the models the relations `has_many` and `belongs_to`. Later, you add the shortcut `has_many :through` to get all paragraphs directly from the document. I would not name the sections table a join table, but from the code, there is a `has_many :through` relation. – mliebelt Oct 14 '11 at 06:05