Forum: Ruby on Rails building and saving has_many and has_one relations

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Wiebe C. (Guest)
on 2007-05-14 17:16
(Received via mailing list)

I am very confused about an aspect of has_one and has_many relations,
with regard to using the build method, and saving the belongs_to side.
It's a somewhat long post. so please bear with me :)

First let's consider the has_one scenario. Let's say I have a student
who must own exactly one car:

class Student

class Car

When I do

student =
car = student.build_car(attributes_of_car)

The car is created, and I can do:!!

I don't understand why build_car also assigns the car to the student.
According to the docs [1], build is an equivalent, in this case, for:"student_id" =>, attributes_of_car)

which does it assign the car to the student. Is that simply a bug in
the docs?

And now comes has_many, which is where the real confusion begins. Take
the same scenario, but now a student can own one or more cars:

class Student

class Car

When I do

student =

Until now, everything is fine, except that the cars are part of the
cars collection of student, which doesn't happen according to the doc
[2]. The real problem comes when I do!

It won't save when there are invalid cars, and the cars are always
invalid, because student_id is still nil: catch 22. Why doesn't rails
automatically handle the student relation of car here, like it does
for the has_one?

Another problem, is that for the has_one, I have to manually call
"valid?" on car, to be able to see invalid fields in the GUI when the
student also has invalid fields (the call to! aborts the
block so that the car is not checked), but for the has_many, calling
"save!" on student automatically marks all invalid cars, and therefore
also all the fields in the GUI.

I hope somebody is able to alleviate my confusion.

This topic is locked and can not be replied to.