Forum: Ruby on Rails Model Association Question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F677fa685a2cfe8aff31f161062db3d3?d=identicon&s=25 David (Guest)
on 2009-06-03 06:06
(Received via mailing list)
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.
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2009-06-03 09:23
(Received via mailing list)
2009/6/3 David <dlynam@gmail.com>:
> 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
F677fa685a2cfe8aff31f161062db3d3?d=identicon&s=25 Dave L (Guest)
on 2009-06-03 09:40
(Received via mailing list)
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.
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2009-06-03 10:09
(Received via mailing list)
2009/6/3 Dave L <dlynam@gmail.com>:
>
> 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
Dd2d775dea75b381edb1bbf0600a0907?d=identicon&s=25 Marnen Laibow-Koser (marnen)
on 2009-06-03 15:56
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
marnen@marnen.org
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2009-06-03 22:25
(Received via mailing list)
2009/6/3 Marnen Laibow-Koser <rails-mailing-list@andreas-s.net>:
>> 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
This topic is locked and can not be replied to.