A "User has_many :files", a "File has_many :users" - How?

User – “has many” :files
File – “has many” :users

How do you define that relationship?

If a user has many files, and each of those files is shared by numerous
other users, how do you define the relationship?

I’m absolutely stuck on this. Any ideas?

I’m also a newbie. Here’s how I do it:

There is a technique called habtm – has and belongs to many.

I am not going to show you habtm, because I don’t use it. Habtm
describes the trivial situation where the pivot table contains only
ids from the two tables it joins. You may find you want other data in
your join table besides just those two ids, and thus you would use the
method I am describing. It is in the section in Agile Rails
Development called “Using Models as Join Tables”.

You make what’s called a “pivot table”, or an “intermediate join
table”. It is a table that sits between your two tables. At the very
least, it has an id from each table. Your model would be called

user_file

your table would be called

user_files

and it would consist of

user_id
file_id

but could have other columns as well.

Then, in your user_file model, you have these lines:

belongs_to :user
belongs_to :file

(notice the pluralization – when you talk about a model on the “one”
side of a one-to-many relationship, it’s singular - -on the many side,
it’s plural)

in your user model, you have these lines

has_many :user_files
has_many :files, :through => :user_files

and your user table must have, at the very least, these columns:

id
user_file_id

then of course in your file model, you have

has_many :user_files
has_many :users, :through => :user_files

and your file model must have, at the very least, these columns

id
user_file_id

And rails style says that all these id columns should be integers, but
if you want to fight that, there are ways.

That’s it, good luck.

Charlie

On Nov 2, 3:38 pm, Bob S. [email protected]

Another (semi?)newbie chiming in:

Charlie described one method, which is certainly good if you have more
complex relationships. But if you really just need a simple many to
many relationship I find join tables and has_and_belongs_to_many works
well.

Your user table has an id field.
Your file table has an id field.
You then have a join table. The join table has only the id from the
other two fields. The name of the join table is the plural forms of
both tables joined with an underscore, in alphabetical order.

If you are using migrations your join table should look something like
this:

create_table “files_users”, :id => false, :force => true do |t|
t.column “file_id”, :integer, :null => false
t.column “user_id”, :integer, :null => false
end

Notice the :id => false. This is so your migration does not create an
id in the join table.

Now, your models.

user.rb

has_and_belongs_to_many :files
#other associations

file.rb

has_and_belongs_to_many :users

Thats it :slight_smile:

If you do a Google search for “rails habtm” you will get lots of
resources.

this looks like a many to many question.
use http://wiki.rubyonrails.org/rails/pages/has_and_belongs_to_many

use in your model:
has_and_belongs_to_many

Thanks Charlie! I really appreciate your help :slight_smile:

You’re the best. Thank you.

Gunde, thank you too!