Wednesday, August 19, 2009

third-order associations using nested :include

The bottom line:

ward_members = Contact.find_all_by_ward(current_user.ward, :include => [{:calling => :calling_type}, :address_group, :photo ])

A little background for non-members:

I'm attending BYU, which is operated by The Church of Jesus Christ of Latter-day Saints.
In Provo, the Mormon Meca, each apartment complex belongs to one or more wards.
A ward (which is an old English word for neighborhood) is a unit of the church of about 300 members and may include members from various neighborhoods and apartment complexes (or a few entire cities in areas where the church is less widespread).
A member may have one or more callings (volunteer responsibility)
There are various types of callings (leadership, teachers, etc)

The Ward Menu (formally called Directory, but referred to as menu as it is often used for dating purposes) that I'm creating will have a few different sections.

Title - a picture and the name of the ward
Bishopric - the 3 primary leaders of the ward
Leadership - various members in positions of leadership, not including the bishopric. Sorted by calling type
Members - photo directory of all members including leadership, but excluding bishopric. Sorted by apartment building or neighborhood, door number, first name.
Index - list of all members as stated above, sorted by first name

I need to generate a query that gets all members, their calling, their calling's type, and their address' group.

@bishopric = Contact.find(:all, :conditions => ["callings.name LIKE ? AND ward_id = ?", 'Bishop%', current_user.contact.ward], :include => [:callings, :photo], :order => 'callings.name')

@leadership = Contact.find(:all, :conditions => ["callings.name IS NOT NULL AND callings.name NOT LIKE ? AND ward_id = ?", 'Bishop%', current_user.contact.ward], :include => [:callings])

@members = Contact.find(:all, :conditions => {:ward_id => current_user.contact.ward}, :include => [:photo], :order => ['address_line_1, address_line_2, first']) - @bishopric

One problem I ran into is that :include does a left join rather than a inner join, but since I'm not up to snaz on my :joins-fu and I don't need the calling info for the photo part of the directory, I decided to just subtract the bishopric from the array. Otherwise @members would only consist of members with callings.

No comments:

Post a Comment