# Odd Join

**URL:** <https://www.ruby-forum.com/t/odd-join/69298>\
**Category:** Rails\
**Created:** [September 20, 2006, 2:52am UTC](https://www.ruby-forum.com/t/odd-join/69298 "2006-09-20T02:52:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [September 20, 2006, 2:52am UTC](https://www.ruby-forum.com/t/odd-join/69298/1 "2006-09-20T02:52:03Z")

</div>

Hey there,

I’m trying to do a really complex join with ActiveRecord and am coming  
up pretty short so far.

The structure is like:

user  
id  
name  
etc.

task  
name  
ect.

task\_assignments  
from\_user\_id  
to\_user\_id  
task\_id

I’m not sure how to model it correctly. I checked out the has\_many  
:through post about doing self referential joins, but that’s for getting  
a user from a user. I want to get the actual task\_assignments from a  
user:

@user.task\_assignments.task.name  
@user.task\_assignments.to.name

etc.

Anyone have any insight into this?

---

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [September 20, 2006, 7:01am UTC](https://www.ruby-forum.com/t/odd-join/69298/2 "2006-09-20T07:01:52Z")

</div>

On 9/20/06, Mike [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> name
> 
> Anyone have any insight into this?  
> @user.task\_assignments is a list of tasks, so you can’t do  
> @user.task\_assignments.task.name - how should the interpreter know  
> which task assignment (out of many) you want the task for?

You’ll have to iterate through the tasks in some way, for example to  
collect all the names:

names = @user.task\_assignments.collect { |assignment|  
assignment.task.name }

or

\<% for assignment in @user.task\_assignments %\>  
\<%= assignment.task.name %\>  
\<%= assignment.to.name %\>  
\<% end %\>

You can also save yourself some typing by declaring

class User  
has\_many :tasks, :through=\>task\_assignments  
end

Read up on “has\_many through”, that should give you some ideas.

Cheers,  
Max

---

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [September 20, 2006, 5:02pm UTC](https://www.ruby-forum.com/t/odd-join/69298/3 "2006-09-20T17:02:23Z")

</div>

Actually, the issue was, the has\_many: through join I was using, linked  
the user, to… the user, not the task. That was the problem.

I’m wonder how to link a user to the actual task itself.

Thanks for the comment.

Max M. wrote:

> On 9/20/06, Mike [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > name
> > 
> > Anyone have any insight into this?  
> > @user.task\_assignments is a list of tasks, so you can’t do  
> > @user.task\_assignments.task.name - how should the interpreter know  
> > which task assignment (out of many) you want the task for?
> 
> You’ll have to iterate through the tasks in some way, for example to  
> collect all the names:
> 
> names = @user.task\_assignments.collect { |assignment|  
> assignment.task.name }
> 
> or
> 
> \<% for assignment in @user.task\_assignments %\>  
> \<%= assignment.task.name %\>  
> \<%= assignment.to.name %\>  
> \<% end %\>
> 
> You can also save yourself some typing by declaring
> 
> class User  
> has\_many :tasks, :through=\>task\_assignments  
> end
> 
> Read up on “has\_many through”, that should give you some ideas.
> 
> Cheers,  
> Max

---

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [September 20, 2006, 11:20pm UTC](https://www.ruby-forum.com/t/odd-join/69298/4 "2006-09-20T23:20:04Z")

</div>

On Sep 20, 2006, at 11:02 AM, Mike wrote:

> > > user  
> > > to\_user\_id
> > 
> > names = @user.task\_assignments.collect { |assignment|
> > 
> > class User  
> > has\_many :tasks, :through=\>task\_assignments  
> > end
> > 
> > Read up on “has\_many through”, that should give you some ideas.
> > 
> > Cheers,  
> > Max

> Actually, the issue was, the has\_many: through join I was using,  
> linked  
> the user, to… the user, not the task. That was the problem.
> 
> I’m wonder how to link a user to the actual task itself.
> 
> Thanks for the comment.

class User \< ActiveRecord::Base  
has\_many :task\_assignments, :foreign\_key =\> ‘to\_user\_id’  
has\_many :tasks, :through =\> :task\_assignments  
has\_many :delegated\_assignments, :class\_name =\>  
‘TaskAssignments’, :foreign\_key =\> ‘from\_user\_id’  
has\_many :delegated\_tasks, :through =\> :delegated\_assignments  
end

class Task \< ActiveRecord::Base  
end

class TaskAssignments \< ActiveRecord::Base  
belongs\_to :task  
belongs\_to :from\_user, :class\_name =\> ‘User’, :foreign\_key =\>  
‘from\_user\_id’  
belongs\_to :to\_user, :class\_name =\> ‘User’, :foreign\_key =\>  
‘to\_user\_id’  
end

puts “Tasks for #{@user.name}:”  
for assignment in @user.tasks  
puts " #{assignment.task.name} from #{assignment.from\_user.name}"  
end

This may not be exactly how you’re setup works, but I think it’s  
accurate. Please let us know how it goes.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid
