# Serialization

## getMemento

The memento pattern is an established pattern in ColdBox apps. A `memento` in this case is a simple representation of your entity using arrays, structs, and simple values.

For instance, the following example shows a User entity and its corresponding memento:

```javascript
component extends="quick.models.BaseEntity" accessors="true" {

    property name="id";
    property name="username";
    property name="email";
    property name="password";
    property name="createdDate";
    property name="modifiedDate";

}
```

```javascript
{
    "id" = 1,
    "username" = "JaneDoe",
    "email" = "jane@example.com",
    "password" = "$2a$04$2nVI5rPOfl6.hrflkhBWOObO5Z7lXGJpi1vlosY74NrL/CKdpWqZS"
    "createdDate" = "{ts '2018-03-12 16:14:10'}",
    "modifiedDate" = "{ts '2018-03-12 16:14:10'}"
}
```

Quick bundles in the excellent [Mementifier](https://www.forgebox.io/view/mementifier) library to handle converting entities to mementos. This gives you excellent control over serialization using a `this.memento` struct on the entity and passing in arguments to the `getMemento` function.

### this.memento

By default, Quick includes all defined attributes as `includes`. You can change this or add other Mementifier options by defining your own `this.memento` struct on your entity. Your custom `this.memento` struct will be merged with Quick's default, so you can only define what changes you need.

Here is the default Quick memento struct. It is inside the `instanceReady()` lifecycle method in this example because `retrieveAttributeNames()` relies on the entity being wired (though not loaded); it is not otherwise necessary to put `this.memento` inside `instanceReady()`.

```javascript
function instanceReady() {
    this.memento = {
        "defaultIncludes" : retrieveAttributeNames( withVirtualAttributes = true ),
          "defaultExcludes" : [],
          "neverInclude"    : [],
          "defaults"        : {},
          "mappers"         : {},
          "trustedGetters"  : true,
          "ormAutoIncludes" : false
    };
}
```

### getMemento Arguments

You can also control the serialization of a memento at call time using Mementifier's `getMemento` arguments.

```javascript
struct function getMemento(
    includes = "", // or []
    excludes = "", // or []
    struct mappers = {},
    struct defaults = {},
    boolean ignoreDefaults = false,
    boolean trustedGetters
)
```

### Custom getMemento

If this does not give you the control you need, you can further modify the memento by overriding the `getMemento` function on your entity. In this case, a `$getMemento` function will be available which is the Mementifier function.

```javascript
component extends="quick.models.BaseEntity" accessors="true" {

    property name="id";
    property name="username";
    property name="email";
    property name="password";
    property name="createdDate";
    property name="modifiedDate";

    function getMemento() {
        return {
            id = getId(),
            username = getUsername(),
            email = getEmail(),
            createdDate = dateFormat( getCreatedDate(), "MM/DD/YYYY" ),
            // can also use getAttribute if you want to bypass a custom getter
            modifiedDate = dateFormat( retrieveAttribute( "modifiedDate" ), "MM/DD/YYYY" )
        };
    }

}
```

```javascript
{
    "id" = 1,
    "username" = "JaneDoe",
    "email" = "jane@example.com",
    "createdDate" = "03/12/2018",
    "modifiedDate" = "03/12/2018"
}
```

## asMemento

Sometimes when retrieving entities or executing a Quick query, you already know you want mementos back. You can skip the step of calling `getMemento` yourself or mapping over the array of results returned by calling `asMemento` before executing the query. `asMemento` takes the same arguments that `getMemento` does. It will pass those arguments on and convert your entities to mementos after executing the query. This works for all the query execution methods - `find`, `first`, `get`, `paginate`, etc.

```cfscript
getInstance( "User" )
    .asMemento( excludes = [ "password" ] )
    .paginate( 1, 10 );
```

## $renderData

The `$renderData` method is a special method for ColdBox. When returning a model from a handler, this method will be called and the value returned will be used as the serialized response. This let's you simply return an entity from a handler for your API. By default this will call `getMemento()`.

```javascript
component {

    // /users/:id
    function show( event, rc, prc ) {
        return getInstance( "User" ).findOrFail( rc.id );
    }

}
```

```javascript
{
    "id" = 1,
    "username" = "JaneDoe",
    "email" = "jane@example.com",
    "createdDate" = "03/12/2018",
    "modifiedDate" = "03/12/2018"
}
```

`QuickCollection` also defines a `$renderData` method, which will delegate the call to each entity in the collection and return the array of serialized entities.

{% hint style="info" %}
Automatically serializing a returned collection only works when using the `QuickCollection` as your entity's `newCollection`.
{% endhint %}

```javascript
component {

    function index( event, rc, prc ) {
        return getInstance( "User" ).all();
    }

}
```

```javascript
[
    {
        "id" = 1,
        "username" = "JaneDoe",
        "email" = "jane@example.com",
        "createdDate" = "03/12/2018",
        "modifiedDate" = "03/12/2018"
    },
    {
        "id" = 2,
        "username" = "JohnDoe",
        "email" = "john@example.com",
        "createdDate" = "03/14/2018",
        "modifiedDate" = "03/15/2018"
    }
]
```

## asQuery

Quick can skip creating entities all together and return an array of structs from qb using the `asQuery` method.

```cfscript
getInstance( "User" )
    .asQuery()
    .paginate( 1, 10 );
```

`asQuery` also supports Eager Loading.  It will add a key matching the relationship name to the returned struct.

```cfscript
getInstance( "Post" )
    .with( "author" )
    .asQuery()
    .paginate( 1, 10 );
```

```json
{
    "id": 1,
    "title": "My First Post",
    "body": "....",
    "author": {
        "id": 1,
        "firstName": "Eric",
        "lastName": "Peterson"    
    }
}
```

{% hint style="info" %}
Using `asQuery` is usually superior to dropping down qb using `retrieveQuery` since it achieves the same purpose while also including automatic aliases and eager loading.
{% endhint %}

### Signature

| Name        | Type    | Required | Default | Description                                                |
| ----------- | ------- | -------- | ------- | ---------------------------------------------------------- |
| withAliases | boolean | `false`  | `true`  | Use the aliases instead of the column names for the query. |

The `withAliases` property is recursive across eager loads.  If you ask for aliases for your initial query (which is the default), all eager loaded queries will also use their respective column aliases.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://quick.ortusbooks.com/guide/serialization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
