Any framework that has convention over configuration has the the problem that newcomers have to learn the conventions.
I think that one of the biggest stumbling blocks to new users of Rails is the way associations are described. Just look at the number of questions on this on SO. M-1 and 1-M and even M-1-M are really quite simple concepts, but the Rails naming of these relationships just serves to confuse.
Here is a good definition that kind of gets at the root cause:
belongs_to and has_many do not describe either the ownership or the scope or the life cycles for the objects they relate. They may give that impression because ‘belongs’ implies ownership and responsibility, but they merely describe the references (the keys) between the objects.
Even the documentation states:
Associations are a set of macro-like class methods for tying objects together through foreign keys
In that case isn’t it easier if we called a spade a spade, and not a shovel?
Surely all the confusion would be cleared up by renaming belongs_to
? This would lower the barrier to learning Rails, resulting in less mistakes, less time wasted asking and answering on SO, less discussions, less blogs → overall a HUGE time saver for the community over the long term (against which you have to weigh the short-term pain of adopting the change of course).
Example 1 - one-to-one
class Employee
has_one :salary
end
class Salary
has_key_for :employee
end
Example 2 - one-to-many
class Manager
has_many :employees
end
class Employee < ActiveRecord::Base
has_key_for :manager
end
Example 3- M-1-M
class Project
has_many :assignments
has_many :employees, through: :assignments
end
class Employee
has_many :assignments
has_many :projects, through: :assignments
end
class Assignment
has_key_for :employee
has_key_for :project
end
Example 4 - Polymorphic
class Address
has_key_for :addressable, :polymorphic => true
end
class Person
has_one :address, as: :addressable
end
I think this just leaves “has_and_belongs_to_many” which personally I have always hated. Why not just use “has_many”? Since when you have an explicit join table for M-M, you use “through”…so if there is no “through” specified, we know it is a HABTM.