In Rails, there are no requirements that both sides of an association be symmetric. In fact, I often find it useful to have asymmetric relationships.

For example, I’m building a mass-mailer. I have parties (people), emails and recipients. Emails are habtm with regards to parties. Since my join table contains other fields besides the two foreign keys, I need a real model for it.

Examine the following code:

 1 class Email < ActiveRecord::Base
 2   has_many :recipients
 3 end
 4 
 5 class Party < ActiveRecord::Base
 6   has_and_belongs_to_many :emails,
 7       :join_table => 'recipients'
 8 end
 9 
10 class Recipient < ActiveRecord::Base
11   belongs_to :email
12   belongs_to :party
13 
14   def read!
15     self.toggle!(:read)
16   end
17 end

The above models give rise to the following very natural code:

 1 >> fbos = Party.find_by_login('fbos')
 2 => #<Party:0x3c019d0 ...>
 3 >> info = Email.create(:subject => 'Latest Schedule',
 4             :body => 'Group schedule: ...')
 5 => #<Email:0x3bece38 ...>
 6 >> info.recipients.create(:party => fbos)
 7 => #<Recipient:0x3bccfd8 ...>
 8 >> fbos.emails
 9 => [#<Email:0x3b80dc0 ...>]

If access to read or unread E-Mail is needed, the habtm association can be declared more than once, with conditions that discriminate between the different states:

1 class Party < ActiveRecord::Base
2   has_and_belongs_to_many :unread_emails,
3       :join_table => 'recipients',
4       :conditions => 'read = 0'
5   has_and_belongs_to_many :read_emails,
6       :join_table => 'recipients',
7       :conditions => 'read = 1'
8 end

Please comment or send me an E-Mail at francois.beausoleil@gmail.com to tell me about your experiences with asymmetric relationships.

Search

Your Host

A picture of me

I am François Beausoleil, a Ruby on Rails and Scala developer. During the day, I work on Seevibes, a platform to measure social interactions related to TV shows. At night, I am interested many things. Read my biography.

Top Tags

Books I read and recommend

Links

Projects I work on

Projects I worked on