Topic: Unsure on how to setup relationships

Hi, I'm looking for some advice on how I might set up the relationships for this app I'm working on. Basically there are entries and an entry belongs to one user (so that only they can edit it). Also other users can add an entry as a favourite (for easy access from their profile page).

I thought the relationships might work like this

User Model

has_many :favourites
has_many :entries, :through => :favourites

Favourite Model

belongs_to :user
belongs_to :entry

Entry Model

has_many :favourites
belongs_to :user

But it doesn't seem quite right and I'm not 100% comfortable with db design so any any pointers on how this could be set up would be great.

Thanks.

Re: Unsure on how to setup relationships

If i understand you right, i think your quite close to your design.

just change the following:

User Model

has_many :favourites
has_many :entries

Favourite Model

belongs_to :user
belongs_to :entry

Entry Model

has_many :favourites
belongs_to :user

the permissions have to be set up and checked in the models. and with this design you can distinguish between an entry created by the user itself (User.entries) and entries form others which the user has just added as favourites. (User.favourites)

I hope this is right...

Re: Unsure on how to setup relationships

Hi andy_r,

I think you need two associations between entries and users: a one-to-many between a user and his entries and a many-to-many between users and their favorite entries. Here's what I mean:

class User < ActiveRecord::Base
  has_many :entries
  has_many :favourites
  has_many :favourite_entries,
           :through => :favourites,
           :class_name => 'Entry',
           :foreign_key => 'entry_id'
end

class Entry < ActiveRecord::Base
  belongs_to :user
  has_many :favourites
  has_many :fans,
           :through => :favourites,
           :class_name => 'User',
           :foreign_key => 'user_id'
end

class Favourite < ActiveRecord::Base
  belongs_to :user
  belongs_to :entry
end


This allows you to access all the entries that a user owns (@user.entries) as well as the ones he has favourited (@user.favourite_entries). It also allows you to find out who an entry belongs to (@entry.user) and who has favourited an entry (@entry.fans).

Maybe I'm being too picky, but personally, I don't like the name of the favourites model: it only makes sense from one side of the association. User#favourites makes some sense (except that you might expect to get the favourite entries and not just the join info), but Entry#favourites doesn't make sense at all. You aren't retrieving an entry's favourite users, you are getting the users who have favourited the entry. Join models are tricky to name, but I think its very important, especially when you are using the associations in your controllers and views down the line. A good name can make your code clearer and more maintainable. I suggest you spend some time coming up with a good name for the join model. Alternatively, if you won't be storing any info in the join other than the user and entry ids, you can just turn it into a join table and use habtm. That way you won't have to name the join at all.

EDIT: maze, sorry, I guess we were responding at the same time. Very similar design.

Last edited by fabio (2007-07-02 04:26:59)