Adapter

Instead of writing ORM-specific code for instancing and persisting created objects, we rely on this interface (and the following default implementation of it). This handles two aspects of factory_botopen in new window: creating an instance of a given model, and then persisting it to the database. (There are other reasons to use it, but that's less important.)

The DefaultAdapter has barebones implementations of each of the interface's functions to keep code DRY and focused only on the methods that matter. The expectation is that any implementations of Adapter will be based on DefaultAdapter.

Example
import {fr, DefaultAdapter} from "fixture-riveter";

export class UserAdapter extends DefaultAdapter {
    // This model needs `isNew` set before any fields are set.
    build<T>(Model: any): T {
        const instance = new Model();
        instance.isNew = true;
        return instance;
    }
}

fr.setAdapter(new UserAdapter(), "user");
1
2
3
4
5
6
7
8
9
10
11
12

Adapter methods

None of the methods on an Adapter will be exposed to the user; they are called internally at various points in the generation of a given fixture. Therefore, the examples below will use the DefaultAdapter to demonstrate how the methods work.

build()

Called to create an instance of the fixture's Model class. Unless specific arguments are required, DefaultAdapter's implementation is generally good enough.

export class DefaultAdapter implements Adapter {
    // ...
    build<T>(Model: any): T {
        return new Model();
    }
    // ...
1
2
3
4
5
6
Arguments
ArgumentTypeDescriptionOptional?
ModelClass functionThe class function (constructor)Required
Return value
TypeDescription
Class instanceInstance of Model
Example
class User {}

const user = adapter.build(User);
user instanceof User
// true
1
2
3
4
5

save()

Called to persist the instance to the database. Must return the persisted instance, not the parameter instance (if there is a difference). Accepts the class function to allow for static methods on the class to handle persistence (for example, Objection.js).

export class DefaultAdapter implements Adapter {
    // ...
    async save<T>(instance: any): Promise<T> {
        return instance.save();
    }
    // ...
1
2
3
4
5
6
Arguments
ArgumentTypeDescriptionOptional?
instanceClass instanceInstance of ModelRequired
ModelClass functionThe class function (constructor)Optional
Return value
TypeDescription
Class instanceThe instance
Example
class User {}

let user = new User();
user.id
// undefined
user = await adapter.save(user, User);
user.id
// 1
1
2
3
4
5
6
7
8

destroy()

Called to delete or remove the instance from the database. Must gracefully handle if the instance has not been persisted to the database (for instance, the instance was constructed with fr.build, not fr.create). Accepts the class function to allow for static methods on the class to handle deletion (for example, Objection.js).

export class DefaultAdapter implements Adapter {
    // ...
    async destroy(instance: any): Promise<void> {
        await instance.destroy();
    }
    // ...
1
2
3
4
5
6
Arguments
ArgumentTypeDescriptionOptional?
instanceClass instanceInstance of ModelRequired
ModelClass functionThe class function (constructor)Optional
Return value
TypeDescription
PromiseA promise
Example
class User {}

let user = new User();
await user.save();
await adapter.delete(user, User);
await User.query().findById(user.id);
// []
1
2
3
4
5
6
7

relate()

Called to "join" two fixture instances together.

WARNING

TODO: clean me up

export class DefaultAdapter implements Adapter {
    // ...
    async relate(instance: any, name: string, other: any): Promise<any> {
        return this.set(instance, name, other);
    }
    // ...
1
2
3
4
5
6
Arguments
ArgumentTypeDescriptionOptional?
instanceClass instanceInstance of a fixtureRequired
namestringProperty on instance to set other toRequired
otherClass instanceInstance of a fixtureRequired
ModelClass functionThe class function (constructor)Optional
Return value
TypeDescription
Class instanceThe instance
Example
class User {}
class Post {
    user: User;
}

const user = new User();
let post = new Post();
post.user
// undefined
post = adapter.relate(post, "user", user);
post.user === user;
// true
1
2
3
4
5
6
7
8
9
10
11
12

set()

Called to set a property on a fixture instance. Returns the whole instance just in case???

WARNING

TODO: clean me up

export class DefaultAdapter implements Adapter {
    // ...
    set(instance: any, key: string, value: any): any {
        instance[key] = value;
        return instance;
    }
    // ...
1
2
3
4
5
6
7
Arguments

(instance: any, key: string, value: any)

ArgumentTypeDescriptionOptional?
instanceClass instanceInstance of a fixtureRequired
keystringProperty on instanceRequired
valueanyA value from an attribute functionRequired
Return value
TypeDescription
Class instanceThe instance
Example
class User {}

let user = new User();
user = adapter.set(user, "firstName", "Noah");
user.firstName
// "Noah"
1
2
3
4
5
6