In Domain Driven Design there is a concept of an Aggregate.
A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the Aggregate, designated as the root.
Simply put: an aggregate has one entity that is designated as the root and an object of the root's class is what you would manipulate in your code. The other entities in an aggregate could not stand on their own outside of the aggregate. It is possible to use the aggregate concept using just ActiveRecord in Rails.
Order entity as an example:
In this example an
OrderLineItem doesn't really make sense outside of
the context of an
Order. Having this in your appliation's global
namespace doesn't really make sense and just clutters it.
You could namespace it with a module, but then you call
Order::Order to use the Order model.
However, if you put the model definition for the order line items in the
Order class definition you get the benefit of namespacing the line items
whilst defining Order as your aggregate root and being the entity that
you interface with in your code.
Here's what that looks like:
class Order < ActiveRecord::Base belongs_to :customer belongs_to :payment has_many :line_items class LineItem < ActiveRecord::Base belongs_to :order belongs_to :item end end
When Rails looks up the table name for LineItem it will look for
order_line_items since the full class name is now
Best of all the
Order class is the interface to get an order's line
Nesting the classes in the same file may seem weird and admittedly you do not have to approach it that way. To me it seems like a better alternative to do that than create a folder and place a separate file for each class, but that seems to indicate more of a namespace to me.
If a aggregate class starts to become unmanageable, then I would try to move more of the functionality to a module that you can include in your class. Using a module will make testing easier anyway.
In the interest of full disclosure: I am by no means a domain driven design expert, or novice even. It was my co-worker Karthik who pointed out to me that what I was doing actually had a DDD term for it.