A bit of a re-post, but I’ve cleaned up the question.
–MODELS–
class Unit < ActiveRecord::Base
has_many :rooms
class Room < ActiveRecord::Base
belongs_to :unit
has_many :rentals
has_many :people, :through => :rentals
class Person < ActiveRecord::Base
has_many :rentals
has_many :rooms, :through => :rentals
class Rental < ActiveRecord::Base
belongs_to :room, :person
–QUESTION–
Using only the unit.id, how can I get the associated person.id?
Unit.find(id).room.rentals.each
{|r|
ids << r.people.id
}
this should work but you could always do individual finds
I slightly altered your instructions into:
def show
@unit = Unit.find(params[:id])
@rooms = @unit.rooms
@unit.room.rentals.each {|r| ids << r.people.id}
end
and get a nasty ‘undefined method `room’ for #Unit:0x4836e8c.’ I
though that @unit would be a class object, but that error implies that
it is just a boring old hash. However, even when I sub your code back
in:
def show
@unit = Unit.find(params[:id])
@rooms = @unit.rooms
Unit.find(params[:id]).room.rentals.each {|r| ids << r.people.id}
end
it gives me the same error, ‘undefined method `room’ for
#Unit:0x4812258.’ If I make a slight typographical edit to pluralize
rooms as:
Unit.find(params[:id]).rooms.rentals.each {|r| ids << r.people.id}
I get one step further but then Rails complains with, ‘undefined method
`rentals’ for Room:Class’ which implies that something is wrong with my
model associations. Any ideas?
hi,
what i understood and as far as my knowledge of rails goes
i tried this
Unit.find(unit.id).rooms.each do |x|
x.rentals.each do |y|
p Person.find(y.person_id)
end
end
gave results
regards
gaurav
On 11/14/06, Taylor S. [email protected] wrote:
and get a nasty ‘undefined method `room’ for #Unit:0x4836e8c.’
I am also kind of stuck here, you can do 2 thigns to check what’s
going wrong. Check the logs for the sql query that’s going to the db,
and see if that’s the one you want. 2. use the debug () function to
print the class of the result. some thing like this in your view <%=
debug(@unit) %>
I know these are not the answers, but it might some how lead to answers.
raj
Taylor S. wrote:
def show
@unit = Unit.find(params[:id])
@rooms = @unit.rooms
@unit.rooms.rentals.each {|r| ids << r.people.id}
end
This won’t work because @unit.rooms returns an array of rental objects,
and that array does not have a rentals method. If have to call the
association methods on the elements inside the rooms array, not on the
whole array itself. So iterate through them and collect the ids.
You need something more like this, with proper responsibilities broken
down between model, controller and view.
Unit model
def people
rooms.collect { |room| room.people }.flatten
end
Controller action
def show
@unit = Unit.find(params[:id])
end
View
<% @unit.people.each do |person| %>
<%= person.name %>
<% end %>
Raj: great tip on the ‘debug’ - it helped me understand what was being
created!
Gaurav: that works but doesn’t integrate with what I want to do.
Alex: iterating over rooms was my problem, thanks for fixing it! I
condensed your answer into what I think is the most graceful solution:
–CONTROLLER–
def show
#get the unit
@unit = Unit.find(params[:id])
#add the rooms
@rooms = @unit.rooms
#add the people
@rooms.collect { |room| room.people }
end
–VIEW–
<% for room in @rooms %>
#a bunch of room data
<% for person in room.people %>
<%= person.first_name + " " + person.last_name %>
<% end %>
<% end %>
The YAML file generated by ‘debug(@unit)’ helped me figure out the right
combination:
— !ruby/object:Unit
attributes:
common_room_width: “20”
floor_number: “1”
rooms:
- !ruby/object:Room
attributes:
window_facing: E
width: "25"
people:
- !ruby/object:Person
attributes:
occupation: steam engineer
<SNIP>
school1: none
THANKS EVERYONE!
On 11/14/06, Taylor S. [email protected] wrote:
has_many :people, :through => :rentals
Using only the unit.id, how can I get the associated person.id?
Person.find_by_sql(…)
AR finders don’t supplant SQL, think of them as convenience methods
for the simple cases…
Isak
Did you try:
class Unit < ActiveRecord::Base
has_many :rooms
has_many :renters, :through => :rooms, :source => :people
And then do a Unit.find(:first).renters for a list of people that are
renting in that unit?
-christos
Unit.find(id).room.rentals.each
{|r|
ids << r.people.id
}
your error was ‘room’ is unidentified method so how about ‘rooms’
Unit.find(id).rooms.rentals.each
{|r|
ids << r.people.id
}