Is there any default way to model something like the following
situation in ActiveRecord?:
A company has_many :buildings which are associated to :company, e.g.
in a polymorphic way.
Moreover one and only one of the buildings is the company's
headquarter.
Thinking in terms of the database, I'd prefer to add an owning
association, an thus have a has_many :buildings plus a
has_one :headquarter, :class => "Building" assocation, where the
foreign key "head_quarter_id" should be assigned to the company and
refer to the buildings table.
I'd prefer that to tagging one building with a headquarter-flag
because there's the advantage of only being forced to change one
dataset (the company, more exactly its headquarter_id), instead of
changing two flags.
be careful: you're building a ring. that's a complex and so trivial
thing.
obvious problem: for a company to store the foreign key of its
headquarter the building has to exist. for that building to store the
foreign key of the company that it belongs to, the company has to
exist.
to simplify it, there are a couple of solutions:
- you could just use an additional attribute in building
"is_headquarter" (bool) <-- your mentioned headquarter flag
- you could add an additional model headquarter that has many
branches, such that "a company has_one headquarter" and "it has_many
branches through headquarter". <-- problem here: hard to upgrade a
branch to headquarter and data-redundancy
- you could create a polymorphic building with an interface for
headquarter and branch
http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations
Thanks very much for the hint - I didn't think of that problem.
- you could create a polymorphic building with an interface for
headquarter and branch
I think it's a good idea to differentiate headquarters and building
using another model (did I get this right?)
Would you suggest - assuming that building belongs_to company in a
polymorphic way - to create a table for headquarters? As it's just a
unique property among the set of buildings belonging to one company
maybe it's good to use STI and let Headquarter inherit from Building.
In the database this would result in a kind of flag (the type column)
as well, but maybe it would cause more readable code and prevent some
"if building.headquarter" patterns.
I agree with Ar that you simply need a join table to hold the
relationship from the Company to its Headquarters instead of using an
object hierarchy and inheritance. Using Modules to insert and
class Company
company_id
end
class Building
building_id
end
class CompanyHeadquarters
company_id
building_id
end
Having the CompanyHeadquarters object may come in handy if you need
extra information about the Headquarters building that is different
from a normal building.
Maybe it's also easier to reflect the situation that a company moves
its headquarter from one building to another. Then there's only the
join table which is affected.