For example, in
class Student < ActiveRecord::Base
has_many :awards
end
class Awards < ActiveRecord::Base
belongs_to :student
end
the above should be the correct usage, but what if we use
class Student < ActiveRecord::Base
has_many :awards
end
class Awards < ActiveRecord::Base
has_one :student
end
doesn't the above also make possible student.awards
as an array of Award objects, and award.student
as a Student object which is the recipient of the award, so works the same way as the method at the top of post?
has_one
is used in case of a one-to-one relationship, not in one-to-many relationships.
Correct use of has_one
:
class Student < ActiveRecord::Base
has_one :id_card
end
class IdCard < ActiveRecord::Base
belongs_to :student
end
The two examples are not equivalent.
has_many
and belongs_to
work as a pair where there is a 'many to one' relationship.
In the database this would look like:
**Students**
Name
Email
...
**Awards**
Name
student_id <-- !IMPORTANT!
...
Each Student
has many awards hence has_many :awards
Each Award
'belongs to' a Student
hence belongs_to :student
Notice that the belongs_to
is applied to the table with the foreign key student_id
. This is important.
OK - so what happens where there is a 'one to one' relationship?
If each student could only have a single award then the database tables could look exactly the same but the model should not be able to return a collection of items.
This is where we need the has_one
declaration. This would be applied to the Student
model in this case. Why? Because the relationship is the same in both directions but Active Record needs to know where to find the foreign key.
If the database tables were the other way around with each Student
having an award_id
then the Student
would get the belongs_to
and the Award
would get the has_one
.
Hope that makes it clear?
It does seem a little odd to be that a student could 'belong to' an award if you use natural language. But that is how the rails active record domain specific language is written.
It gets even more unnatural sounding when you look at the 'many to many' relationship with 'has_many_and_belongs_to'. Here there is a joining table which site between your main tables like
students_awards
student_id
award_id
In this situation neither the Students
nor the Awards
table have a foreign key but both will carry the has_many_and_belongs_to :other_table
declaration. Both tables are able to join to multiple rows of the other. Each Student
can have more than one Award
. Each Award
can be applied to many Students
.
The has_one
declaration is only used where there is a 'one-to-one' relationship and the table it applies to does not have the foreign key.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With