Moving away from the Active Record model
Fowler defines Active Record as:
An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.
Note that I am talking about the Active Record pattern and not a particular Active Record implementation.
A typical Active Record class will look like this:
By design, AR entities suffer from one major problem, they violate SRP, since the class is now responsible for its own persistence and for the business operations that relates to it. But that is an acceptable decision in many cases, because it leads to code that is much simpler to understand.
In most cases, that is.
The problem with AR is that it also treat each individual entity independently. In other words, its usage encourage code like this:
var person = Person.FindBy("Id", 1); person.Name = "Oren"; person.Save();
This is a very procedural way of going about things, but more importantly, it is a way that focus on work done on a single entity.
When I compare the abilities of the Active Record style to the abilities of a modern ORM, there is really nothing that can compare. Things like automatic change tracking or batching writes to the database are part of the package with an ORM.
The sort of applications we write today aren’t touching a single row in the database, we tend to work with entities (especially root aggregates) with operations that can touch many rows. Writing those sort of applications using Active Record leads to complications, precisely because the pattern is meant to simplify data access. The problem is that our data access needs aren’t so simple anymore.
Active Record can still be useful for very simple scenarios, but I think that a major drive behind it was that it was so easy to implement compared to a more full featured solution. Since we don’t need to implement a full featured solution (it comes for free with your ORM of choice), that isn’t really a factor anymore. Using a full blown ORM is likely to be easier and simpler.