Using ruby methods map and zip along with Rails extended finds
This is a combination of techniques that I find useful when you need to output related data from various database tables in the same list.
In this example I have organisations, users and a linking table between the two called jobs; each user can only have one job with an organisation, but they can have many jobs.
I want to output a list of users, for a particular organisation, along with information about their job with that organisation.
In the controller I pull out all the information I need:
@organisation = Organisation.find(params[:id])
@users = @organisation.users
@jobs = @users.map { |user| user.jobs.organisation(@organisation) }
@users_with_jobs = @users.zip(@jobs)
@users contains all the users for the organisation. The clever bit is in utilising the ruby map method and an extended find to allow me to get the job information for each user I just pulled out into @users to create a second array @jobs.
The user.jobs.organisation(@organisation) method is an extended find in my User model:
has_many :jobs do
def organisation(organisation)
find(:first, :conditions => ["organisation_id = ?", organisation.id])
end
end
That method allows me to search the jobs for a user and just pull out the job for a particular organisation.
Using the zip method I combine the @users and @jobs arrays into one instance variable that I can loop through. As I've created them using the map method I know they will match up.
Now back in my view I can do:
@users_with_jobs.each do |user, job|
user.name
job.name
end
I could have just used my extended find in the view like this:
@users.each do |user|
user.name
user.jobs.organisation(@organisation).name
end
But I want to keep the view simple and do all the data collection in the controller.
As a note the zip method works like this:
a = [1,2,3]
=> [1, 2, 3]
b = [4,5,6]
=> [4, 5, 6]
a.zip b
=> [[1, 4], [2, 5], [3, 6]]
b.zip a
=> [[4, 1], [5, 2], [6, 3]]
About
Paul is a web developer for Kyanmedia web agency. He's lucky enough to write in Ruby on Rails full-time and uses this site to post snippets of code.
Contact
my name at gmail.com
More snippets
Take a look in the archive
Need a website?
Contact my employer. Make sure to check out our portfolio of work.
Hosting
I recommend hostingrails.com
5 comments made
Hello Paul,
Thank you for this very helpful resource. I’ve tried to find more documentation on the Rails extended find you used in this example. Unfortunately, the Rails Framework Documentation doesn’t describe this facility. Do you know of any references on the subject?
Thank you for your attention,
marc
Hi Marc,
I’ve just checked my bookmarks and I can’t find anything on extended finds. Neither could I via Google, although I definitely remember reading about them somewhere.
Anyway, I’ll have to write my own article about them to explain their glory in detail. I couldn’t code without them now!
Cheers,
Paul.
Great blog!
I also host mine on hostingrails.com
cheers!
I also have some questions regarding your blog app, hope you don’t mind drop me an email
Just for Marc and Paul. The official name in rails for this is “Association extensions”. Try your google search again!
Got something to say?