# Model Association Question

**URL:** <https://www.ruby-forum.com/t/model-association-question/169387>\
**Category:** Rails\
**Created:** [June 3, 2009, 6:06am UTC](https://www.ruby-forum.com/t/model-association-question/169387 "2009-06-03T06:06:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [June 3, 2009, 6:06am UTC](https://www.ruby-forum.com/t/model-association-question/169387/1 "2009-06-03T06:06:30Z")

</div>

It seems like there may be a rails method for the following situation:  
model User  
has\_many :appointments

model Appointment  
has\_one :instruction  
belongs\_to :user

model Instruction  
belongs\_to :appointment

I would like to do User.Appointments.Instruction and return an array  
with instruction objects but no go. I am doing the following and  
wondering if there is a cleaner way?

appointments = logged\_in\_user.appointments  
@instructions = Array.new  
appointments.each do |appointment|  
@instructions.push(appointment.instruction)  
end

Thanks for any help/input.

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [June 3, 2009, 9:23am UTC](https://www.ruby-forum.com/t/model-association-question/169387/2 "2009-06-03T09:23:05Z")

</div>

2009/6/3 David [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> belongs\_to :appointment
> 
> I would like to do User.Appointments.Instruction and return an array  
> with instruction objects but no go. Â I am doing the following and  
> wondering if there is a cleaner way?
> 
> appointments = logged\_in\_user.appointments  
> Â Â Â @instructions = Array.new  
> Â Â Â appointments.each do |appointment|  
> Â Â Â Â @instructions.push(appointment.instruction)  
> Â Â Â end

Something like  
@instructions = logged\_in\_user.appointments.collect { |a|  
[a.instruction] }

Though I think I would consider something like putting this in a  
method of User that returned an array of instructions for that user.  
Or a class method or User that does it for the current logged in user.  
Dependent on the rest of your requirements of course. You might want  
to consider a class member of Appointments that takes an array of  
appointments and returns an array of instructions.

Colin

Colin

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [June 3, 2009, 9:40am UTC](https://www.ruby-forum.com/t/model-association-question/169387/3 "2009-06-03T09:40:11Z")

</div>

Okay, thanks a lot. That really helps. For the logged\_in\_user, that  
would be a User instance method, right? Something like:

Class User \< ActiveRecord::Base  
def return\_instructions\_array  
instructions = Instructions.return\_array(self.appointments)  
end  
end

This would be an Instructions class method…is this better than an  
Instruction instance method? like:

Instructions.new.return\_array(self.appointments)

I’m never really sure which is better.

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [June 3, 2009, 10:09am UTC](https://www.ruby-forum.com/t/model-association-question/169387/4 "2009-06-03T10:09:03Z")

</div>

2009/6/3 Dave L [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Okay, thanks a lot. Â That really helps. Â For the logged\_in\_user, that  
> would be a User instance method, right? Â Something like:
> 
> Class User \< ActiveRecord::Base  
> Â def return\_instructions\_array  
> Â Â instructions = Instructions.return\_array(self.appointments)  
> Â end  
> end

It is a matter of taste, but I would probably just call it  
instructions, and you don’t actually need the assignment operation, a  
method automatically returns the last value determined so I would  
possibly use

def instructions  
Instructions.appointments(self.appointments)  
end

Then the call reads intuitively  
@instructions = User.instructions

Or maybe better if it were called current\_instructions to indicate  
that it is the current user. I always try and make the code read so  
that it as clear as possible what is happening without having to use  
any more comments than necessary.

> This would be an Instructions class method…is this better than an  
> Instruction instance method? Â like:
> 
> Instructions.new.return\_array(self.appointments)

There is no point making it an instance method, it just means you have  
to make an instance in order to call it. Generally if a method is  
acting on a single instance of a class then it should be an instance  
method, if it is acting on a set of them then make it a class method.  
Not that I am a Ruby expert, there may well be a more elegant way of  
achieving this.

Colin

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [June 3, 2009, 3:56pm UTC](https://www.ruby-forum.com/t/model-association-question/169387/5 "2009-06-03T15:56:03Z")

</div>

David wrote:

> It seems like there may be a rails method for the following situation:  
> model User  
> has\_many :appointments
> 
> model Appointment  
> has\_one :instruction  
> belongs\_to :user
> 
> model Instruction  
> belongs\_to :appointment
> 
> I would like to do User.Appointments.Instruction and return an array  
> with instruction objects

Try User :has\_many instructions, :through =\> appointments. I think that  
will define User#instructions, which should do exactly what you want.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [June 3, 2009, 10:25pm UTC](https://www.ruby-forum.com/t/model-association-question/169387/6 "2009-06-03T22:25:59Z")

</div>

2009/6/3 Marnen Laibow-Koser [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > model Instruction  
> > belongs\_to :appointment
> > 
> > I would like to do User.Appointments.Instruction and return an array  
> > with instruction objects
> 
> Try User :has\_many instructions, :through =\> appointments. Â I think that  
> will define User#instructions, which should do exactly what you want.

That’s much better, I should have thought of that. I have learnt more  
here attempting to answer questions than I have through the questions  
I have asked myself.

Colin
