Single association through multiple sources

I have two tables that need to be associated: projects and users. Users
related to projects in one of two ways: they are either the project
lead, and/or they have a job on the project. Currently, the user model
looks like this:

has_many :projects, :through => :jobs, :group => “projects.id”,
:conditions => “projects.lead_id != jobs.user_id”
has_many :jobs
has_many :lead_projects, :class_name => “Project”, :foreign_key =>
“lead_id”

The problem with this is that if I want to get every project that a user
relates to, I have to do it like this:

@projects = current_user.projects
@projects += current_user.lead_projects

This is a problem because it sticks the projects that the user is the
lead on at the end of the collection. Is there any way that I can
combine user.projects to contain both projects and :lead_projects?

Failing that, is there any way I can re-order the @projects collection
based on different attributes?

Thanks :slight_smile:

at first i thought this might be an easy solution but then i realized
that there is a hmt association with users/jobs/projects and that
makes things more difficult.

I will however suggest a change and see if this works for you.
assuming a job is something like “tester”, “developer”, etc., why not
make “lead” a job as well and remove the lead_id from the project
altogether?

that would leave you with:

class Project < AR::Base
has_many :jobs
end

class Job < AR::Base
belongs_to :project
belongs_to :user
end

class User < AR::Base
has_many :jobs
has_many :projects, :through => :jobs do
def by_jobname(jobname)
find(:all, :conditions => [“jobs.name = ?”, jobname])
end

def lead
  find(:all, :conditions => "jobs.name = 'lead'")

end
end

then you can use the above association extensions like so:

u = User.find(…)

u.projects # => all projects in which the user has a job
u.projects.by_jobname(‘developer’) # => all projects where user has a
developer job
u.projects.lead # => all projects where user has a lead job

you could even do the same with projects to find users based on job.

see:

section on association extensions for more info.

hope this helps

Chris

This is great to know, but unfortunately lead and jobs are quite a bit
different. I considered this approach already but it would mess up my
app in a bunch of other places, and require me to remove/change a few
key features. I’m thinking that just re-ordering the collection that I
get when I combine user.projects and user.lead_projects might be the way
to go. Is this something I can do?

Thanks again