In my previous post, I talked about some of the options we have to persist value objects in a relational database. In this one, I’m going to show an example using Rails and the denormalised database approach.
Let’s say we want to model a Client entity which has an Address. In the Entities and Value Objects post, I already used an Address value object as an example, let’s bring it back
Following the denormalised database approach, we’ll put together in the same database table the Client and the Address attributes. In Rails this would result in a migration similar to this
In Rails we can say that ActiveRecord models are entities where the identity is provided by the ActiveRecord id. If we model the Client as an entity, the Client class could be something like
Since one of the value objects’ main characteristics is immutability, in order to prevent unwanted modification attempts from the Client, this implementation restricts the access of Rails attribute writers to private.
It’s also worth mentioning that this denormalised approach can be handy when you are trying to extract behaviour from a convoluted Rails model. Imagine a Client model in which the Address attributes are already part of it, extracting a value object is trivial since there is no need to touch the database scheme. In fact, this refactor is a common one in articles that talk about refactoring fat ActiveRecord models.
And that’s it, we have a Client entity that has a value object Address where all its attributes (Client and Address attributes) are persisted in the same database table.