Repository Pattern vs Active Record Pattern Compatibility

activerecordarchitectural-patternsdesign-patternsentitypatterns-and-practices

Currently I am developing a webapp where I have defined models implementing the Active Record pattern. Each model also is defined by an interface that specifies the Entity properties and makes it easy to inject it into other classes, specially useful for unit testing.
I am looking forward to implement each model with a Repository pattern to abstract the database implementation.

e.g. Article:

ArticleInterface
- title
- content

ArticleRepositoryInterface
- getArticle(title)
- saveArticle(ArticleInterface)

ArticleRepository implements ArticleRepositoryInterface
- constructor(ArticleInterface)
- ArticleInterface getArticle(title)
- saveArticle(ArticleInterface)

Article implements ArticleInterface extends ActiveRecordModel

Both patterns are very popular in today web development frameworks, but It is not clear to me how to integrate them.
The Active Record pattern by definition wraps a row in a database table, encapsulates the database access, mapping each object property to a database table, so

  • how should you integrate each model repository with the model that implements the AR ?

  • Are there any alternatives to using a model that implements the AR, inheriting all the database methods, and injecting it into a Repository wrapping all the AR database methods?

  • What are the best practices in this scenario?

If it adds any context to this question, I'm using Laravel and Eloquent.

Best Answer

The repository pattern:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

The Data Mapping layer that you've chosen is Active Record. Ergo, the Repository is that software pattern that provides an additional layer of abstraction between your Active Record pattern and your business domain.

How should you integrate each model repository with the model that implements the AR?

By providing methods that return a collection-like interface to your business domain, using Active Record to retrieve the necessary results from the database.

Are there any alternatives to using a model that implements the AR, inheriting all the database methods, and injecting it into a Repository wrapping all the AR database methods?

You can use some other method for accessing the database, like Table Data Gateway, Row Data Gateway or Data Mapper, in place of Active Record.

What are the best practices in this scenario?

Those practices that best meet your software's functional and non-functional requirements in terms of performance and maintainability.