Undefined method with Active Record joins

In my application there are four models:

Units: id, name (has_many :rooms)
Rooms: id, name (has_many :rentals, belongs_to :units)
People: id, name (has_many :rentals)
Rentals: room_id, people_id, created_at, ended_at (belongs_to :rooms,
:people)

Rooms may have more than one person, but a person can only live in one
room (as defined by a NULL ended_at). Before a person can move into a
new room, s/he must “move_out” by setting ‘ended_at.’ This I can deal
with. I want to list the rooms and, if occupied, the name(s) of their
people. Here are my attempts:

@unit = Unit.find(params[:id])
@rooms = @unit.rooms
@people = @unit.rooms.people

gives --> undefined method `people’ for Room:Class

@unit = Unit.find(params[:id])
@rooms = @unit.rooms
@people = @unit.rooms.rentals.people

gives --> undefined method `rentals’ for Room:Class

What am I doing wrong?

When you have a has_many then unit.rooms will return an array of rooms
(well a collection proxy that looks like one), which doesn’t have a
rentals method.
Each object in that collection does, so you can get all rentals for your
unit by iterating over @unit.rooms

Fred

Rooms: id, name (has_many :rentals, belongs_to :units)
People: id, name (has_many :rentals)
Rentals: room_id, people_id, created_at, ended_at (belongs_to :rooms,
:people)

So Rentals is a join table between Rooms 6 people, correct?

try this:

Rooms:
has_many :rentals
has_many :people, :through => :rentals

People:
has_many :rentals
has_many: rooms, :through => :rentals

that should enable you to do @unit.rooms.people

Rooms:
has_many :rentals
has_many :people, :through => :rentals

People:
has_many :rentals
has_many: rooms, :through => :rentals

that should enable you to do @unit.rooms.people

I still get an undefined method for Room. Any other suggestions?

THE CLASSES
class Unit < ActiveRecord::Base
has_many :rooms
end

class Room < ActiveRecord::Base
belongs_to :units
has_many :rentals
has_many :people, :through => :rentals
end

class Person < ActiveRecord::Base
has_many :rentals
has_many :rooms, :through => :rentals
end

class Rental < ActiveRecord::Base
belongs_to :rooms, :people
end

THE ACTION
def show
@unit = Unit.find(params[:id])
@rooms = @unit.rooms
@people = @unit.rooms.people
end

THE ERROR
NoMethodError in UnitsController#show
undefined method `people’ for Room:Class

A few fixes, but still same error: all singular / pluralization issues
have been fixed on the Classes.

Can’t do that. Proxies only work one level deep. When you think about
it,
@unit.rooms returns a bunch of Room objects. Invoking a single
association
on a collection of objects doesn’t make sense. You need to iterate them.

At least that’s how it looks to me from your class definitions.

Jacquie F. wrote:

has_many :rentals
class Rental < ActiveRecord::Base


View this message in context:
http://www.nabble.com/-Rails--Undefined-method-with-Active-Record-joins-tf2615629.html#a7312225
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Steve R. wrote:

Can’t do that. Proxies only work one level deep. When you think about
it,
@unit.rooms returns a bunch of Room objects. Invoking a single
association
on a collection of objects doesn’t make sense. You need to iterate them.

At least that’s how it looks to me from your class definitions.

I played with it a while but couldn’t get anywhere. How can I grab the
person’s name and id based on the unit? Maybe I should give up on using
Rentals as a model and use a people_rooms join table instead?