# Overview of the Active Record Pattern

## Definition

**The active record design pattern** (considered an architectural pattern) is an approach that connects the application's business logic to a database table, allowing developers to work with the database using an object-oriented paradigm.

**The active record** is an object that wraps a row in the database table, encapsulates the database access and provides an interface to query, insert, update and delete data from the database, making it easier to work with databases in an application.

In addition to query, insert, update and delete functions, the interface on an object conforming to this pattern would also include properties that correspond more or less directly to the columns in the underlying database table.

After the creation of an object, a new row is added to the table upon saving. Any object loaded gets its information from the database. When an object is updated, the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view.

The active record pattern is commonly used by many programming frameworks that store in-memory object data in relational databases, such as Django and Laravel.

## Name origin

The pattern was named by Martin Fowler in his book [Patterns of Enterprise Application Architecture](https://amzn.to/3uawkEy) (2003).

## Implementation

This pattern is intended to make simple CRUD (Create, Read, Update, Delete) tasks quicker to achieve. For example, instead of writing a lot of SQL queries to insert or update many common and simple data objects, it allows us to simply assign values to the data object and run a command to save it, e.g. `$object->save()`. The SQL for inserting/updating data will be compiled and executed for us.

For example, if there is a table `users` in a database with columns `name` (string type) and `age` (number type), and the Active Record pattern is implemented in the class `User`, the pseudo-code will create a new row in the `users` table with the given values:

```php
$user = new User();
$user->name = 'John Doe';
$user->age = 25;
$user->save();
```

The pseudo-code above is roughly equivalent to the SQL command:

```sql
INSERT INTO users (name, age) VALUES ('John Doe', 25);
```

Conversely, the class can be used to query the database:

```php
$user = User::where('name', 'John Doe')->first();
```

This will find a new `User` object based on the first matching row from the `users` table whose `name` column has the value "John Doe". The SQL command used might be similar to the following, depending on the SQL implementation details of the database:

```sql
SELECT * FROM users WHERE name = 'John Doe' LIMIT 1;
```

Most frameworks also implement data relationships within their respective Active Record models which can greatly simplify accessing data related to our object. For example, in Laravel, if we specified that a `Category` "has many" `Product`\`s then after loading the `Category` object from the database, we can list its child `Product`\`s with a simple line of code:

```php
foreach ($category->products as $product) {
  echo $product->name;
}
```

## When to use it

Active Record is a good choice for domain logic that is not too complex, such as creates, reads, updates, and deletes. Derivations and validations based on a single record work well in this structure.

## Criticism

#### Mapping issues

Active Record has the primary advantage of simplicity. It is easy to build Active Records, and they are easy to understand. Their primary problem is that they work well only if the Active Record objects correspond directly to the database tables: an isomorphic schema.

If your business logic is complex, you will soon want to use your object's direct relationships, collections, inheritance, and so forth. These do not map easily onto Active Record, and adding them piecemeal gets very messy. That is what will lead you to use Data Mapper instead.

#### Testability

Due to the coupling of database interaction and application logic when using the active record pattern, unit testing an active record object without a database becomes difficult. These negative effects on the testability of the active record pattern can be reduced by using mocking or dependency injection frameworks to substitute the real data tier with a simulated one.

#### Distributed systems

Record-based patterns work poorly in distributed systems, especially where concurrency is impossible (e.g. offline). i.e. two updates both may have one field that is correct but only one of the two records can win.

#### Single responsibility principle and separation of concerns

Due to the strong coupling of database interaction and application logic, an active record object does not follow the single responsibility principle and separation of concerns as opposed to multitier architecture which properly addresses these practices.

## Conclusion

Active Record is good for quick CRUD-based applications where the Model is relatively flat (as in, not a lot of class hierarchies). However, for applications with complex OO hierarchies, a DataMapper is probably a better solution.

---

I hope you found this information helpful, stay tuned for more content! :)

---

## Source

1. [Active record pattern - Wikipedia](https://en.wikipedia.org/wiki/Active_record_pattern)
    
2. [What is the purpose of Active Records? - StackOverflow](https://stackoverflow.com/questions/1404405/what-is-the-purpose-of-active-records)
    
3. [Patterns of Enterprise Application Architecture (2003)](https://amzn.to/3uawkEy)
