Model Association Question


#1

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.


#2

2009/6/3 David 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


#3

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.


#4

2009/6/3 Dave L 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


#5

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
removed_email_address@domain.invalid


#6

2009/6/3 Marnen Laibow-Koser 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