How To Delegate to the Join Model?


I’m wondering if someone can help me with this. I have a
situation where I need to store information in the join model of a
has_many :through to assist with genearting views. But I can’t
think of an
elegant and efficient solution.

Heres an example of some code:

class Mailbox < AR::B
has_many :mailbox_contents
has_many :postcards, :through => ‘mailbox_contents’

class PostCard < AR::B

has_many :mailbox_contents
has_many :mailboxes, :through => ‘mailbox_contents’

class MailboxContent < AR::B
belongs_to :mailbox
belongs_to :postcard

So then I want to be able to have a default view for the post card in each mailbox.

to do this I put a column called default_view into the
MailboxContent model so that I can track default_view per postcard
inside each book.

This is because users share postcards. They can exist in multiple
users mailboxes, and each user may want to see the image, or the

I came up with the following in the controller.

def index
@mailbox = Mailbox.find( :include => :mailbox_contents, :conditions => { :mailbox_id => params[:mailbox_id] } )
@postcards = @mailbox.postcards

And then in the view

<% @postcards.each do |pc| %>
View Type
<%= @mailbox.mailbox_contents.find_by_postcard_id( postcard ).default_view %>
<% end %>

shudder Ugly

I would like to go the other way and use something like


but I guess it would have to be postcard.default_view_for( @mailbox )

I guess the controller code would then change to

def index
@mailbox = MailBox.find( paras[:id] )
@postcards = @mailbox.postcards.find( :all, :include => [:mailbox_contents] )

Then in the postcard model

class Postcard AR::B
def default_view_for( mailbox )
self.mailbox_contents.find_by_mailbox_id( mailbox )

The question is, would doing this, eager loading in the controller,
then accessing the collection in the model, prevent a whole heap of db
requests in the view?

I’m hoping it will since I think the mailbox_contents association should be cached for each model.

Any thoughts on a more elegant and or efficient way of doing this?