-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Need to figure out an API for handling associations between entity types. Some options:
interface User {
id: number;
name: string;
posts: Array<Post>
tenantId: number;
}
interface Post {
id: number;
userId: number;
title: string;
body: string;
}
// Option A
const userFactory = createFactory((factory) =>
factory
.attributes<User>({
id: 1,
name: 'Alice',
tenantId: 1,
posts: () => []
})
.hasOne('tenant')
.hasMany('posts')
);
const postFactory = createFactory((factory) =>
factory
.attributes<Post>({
id: 1,
userId: 1,
title: 'title',
body: 'body',
})
.hasOne('user')
);
const tenant = db.tenants.create();
const user = db.users.create({ tenant }) // sets tenantId on user
const posts = db.posts.createList(3, { user }); // sets userId on posts (sets posts on user or no?)
// Option B
// This would be awkward because attribute builders aren't invoked when the definition is evaluated.
// Would have to iterate through each attribute builder and invoke it to see if it's an association.
// Advantage is that this could work with attributes-only notation
const userFactory = createFactory((factory) =>
factory
.attributes<User>({
id: 1,
name: 'Alice',
tenantId: ({ hasOne }) => hasOne('tenant'),
posts: ({ hasMany }) => hasMany('posts')
})
);
const postFactory = createFactory((factory) =>
factory
.attributes<Post>({
id: 1,
userId: ({ hasOne }) => hasOne('user'),
title: 'title',
body: 'body',
})
);
// Option C
const userFactory = createFactory((factory) =>
factory
.attributes<User>({
id: 1,
name: 'Alice',
tenantId: factory.hasOne('tenant'),
posts: factory.hasMany('posts')
})
);
const postFactory = createFactory((factory) =>
factory
.attributes<Post>({
id: 1,
userId: factory.hasOne('user'),
title: 'title',
body: 'body',
})
);
// Option D
// - Doesn't feel right to break away from the builder pattern, could be confusing
// to mix dsl patterns
// - Terseness is nice
// - Works with builder and attribute notation
import { createFactory, hasOne, hasMany } from 'typical-data';
const userFactory = createFactory<User>({
id: 1,
name: 'Alice',
tenantId: hasOne('tenant'),
posts: hasMany('posts')
});
const postFactory = createFactory<Post>({
id: 1,
userId: hasOne('user'),
title: 'title',
body: 'body',
});
// Option E
const userFactory = createFactory('user', (factory) =>
factory
.attributes<User>(({ primaryKey, hasMany, hasOne }) => ({
id: primaryKey(),
name: 'Alice',
posts: hasMany('post')
}))
);
const postFactory = createFactory('post', (factory) =>
factory
.attributes<Post>(({ primaryKey, hasOne }) => ({
id: primaryKey(),
author: hasOne('user'),
title: 'title',
body: 'body',
}))
);
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request