refactor: minimize repeated code by re-using parseInclude, parseWhere and getMethod

feat(include): ability to specify multiple includes, as an array
This commit is contained in:
Mahdi Dibaiee
2016-03-10 10:48:30 +03:30
parent 00e8e89767
commit 11291f0e08
8 changed files with 226 additions and 257 deletions

View File

@ -1,15 +1,16 @@
import joi from 'joi';
import error from '../error';
import { capitalize } from 'lodash/string';
import { getMethod } from '../utils';
let prefix;
export default (server, a, b, options) => {
export default (server, a, b, names, options) => {
prefix = options.prefix;
server.route({
method: 'GET',
path: `${prefix}/associate/${a._singular}/{aid}/${b._singular}/{bid}`,
path: `${prefix}/associate/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
@error
async handler(request, reply) {
@ -25,12 +26,15 @@ export default (server, a, b, options) => {
}
});
let fna = (instancea['add' + b.name] || instancea['set' + b.name]).bind(instancea);
let fnb = (instanceb['add' + a.name] || instanceb['set' + a.name]).bind(instanceb);
const fna = getMethod(instancea, names.b, false, 'add') ||
getMethod(instancea, names.b, false, 'set');
const fnb = getMethod(instanceb, names.a, false, 'add') ||
getMethod(instanceb, names.a, false, 'set');
await fna(instanceb);
await fnb(instancea);
reply(instancea);
reply([instancea, instanceb]);
}
})
}

View File

@ -1,118 +1,94 @@
import joi from 'joi';
import error from '../error';
import _ from 'lodash';
import { parseInclude, parseWhere, getMethod } from '../utils';
let prefix;
export default (server, a, b, options) => {
export default (server, a, b, names, options) => {
prefix = options.prefix;
get(server, a, b);
list(server, a, b);
scope(server, a, b);
scopeScope(server, a, b);
destroy(server, a, b);
destroyScope(server, a, b);
update(server, a, b);
get(server, a, b, names);
list(server, a, b, names);
scope(server, a, b, names);
scopeScope(server, a, b, names);
destroy(server, a, b, names);
destroyScope(server, a, b, names);
update(server, a, b, names);
}
export const get = (server, a, b) => {
export const get = (server, a, b, names) => {
server.route({
method: 'GET',
path: `${prefix}/${a._singular}/{aid}/${b._singular}/{bid}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
@error
async handler(request, reply) {
let include = [];
if (request.query.include)
include = [request.models[request.query.include]];
const include = parseInclude(request);
let instance = await b.findOne({
const base = a.findOne({
where: {
id: request.params.bid
},
include: include.concat({
where: {
id: request.params.aid
},
model: a
})
id: request.params.aid
}
});
const method = getMethod(base, names.b);
const list = await method({ where: {
id: request.params.bid
}, include });
reply(list);
}
})
}
export const list = (server, a, b) => {
export const list = (server, a, b, names) => {
server.route({
method: 'GET',
path: `${prefix}/${a._singular}/{aid}/${b._plural}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}`,
@error
async handler(request, reply) {
let include = [];
if (request.query.include)
include = [request.models[request.query.include]];
const include = parseInclude(request);
const where = parseWhere(request);
let where = _.omit(request.query, 'include');
for (const key of Object.keys(where)) {
try {
where[key] = JSON.parse(where[key]);
} catch (e) {
//
const base = await a.findOne({
where: {
id: request.params.aid
}
}
let list = await b.findAll({
where,
include: include.concat({
where: {
id: request.params.aid
},
model: a
})
});
const method = getMethod(base, names.b);
const list = await method({ where, include });
reply(list);
}
})
}
export const scope = (server, a, b) => {
export const scope = (server, a, b, names) => {
let scopes = Object.keys(b.options.scopes);
server.route({
method: 'GET',
path: `${prefix}/${a._singular}/{aid}/${b._plural}/{scope}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}/{scope}`,
@error
async handler(request, reply) {
let include = [];
if (request.query.include)
include = [request.models[request.query.include]];
const include = parseInclude(request);
const where = parseWhere(request);
let where = _.omit(request.query, 'include');
for (const key of Object.keys(where)) {
try {
where[key] = JSON.parse(where[key]);
} catch (e) {
//
const base = await a.findOne({
where: {
id: request.params.aid
}
}
});
let list = await b.scope(request.params.scope).findAll({
const method = getMethod(base, names.b);
const list = await method({
scope: request.params.scope,
where,
include: include.concat({
where: {
id: request.params.aid
},
model: a
})
include
});
reply(list);
@ -129,7 +105,7 @@ export const scope = (server, a, b) => {
})
}
export const scopeScope = (server, a, b) => {
export const scopeScope = (server, a, b, names) => {
let scopes = {
a: Object.keys(a.options.scopes),
b: Object.keys(b.options.scopes)
@ -137,23 +113,12 @@ export const scopeScope = (server, a, b) => {
server.route({
method: 'GET',
path: `${prefix}/${a._plural}/{scopea}/${b._plural}/{scopeb}`,
path: `${prefix}/${names.a.plural}/{scopea}/${names.b.plural}/{scopeb}`,
@error
async handler(request, reply) {
let include = [];
if (request.query.include)
include = [request.models[request.query.include]];
let where = _.omit(request.query, 'include');
for (const key of Object.keys(where)) {
try {
where[key] = JSON.parse(where[key]);
} catch (e) {
//
}
}
const include = parseInclude(request);
const where = parseWhere(request);
let list = await b.scope(request.params.scopeb).findAll({
where,
@ -176,33 +141,23 @@ export const scopeScope = (server, a, b) => {
})
}
export const destroy = (server, a, b) => {
export const destroy = (server, a, b, names) => {
server.route({
method: 'DELETE',
path: `${prefix}/${a._singular}/{aid}/${b._plural}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}`,
@error
async handler(request, reply) {
let where = _.omit(request.query, 'include');
const include = parseInclude(request);
const where = parseWhere(request);
for (const key of Object.keys(where)) {
try {
where[key] = JSON.parse(where[key]);
} catch (e) {
//
}
}
let list = await b.findAll({
where,
include: {
model: a,
where: {
id: request.params.aid
}
}
const base = await a.findOne({
where: request.params.aid
});
const method = getMethod(base, names.b);
const list = await method({ where, include });
await* list.map(instance => instance.destroy());
reply(list);
@ -210,34 +165,29 @@ export const destroy = (server, a, b) => {
})
}
export const destroyScope = (server, a, b) => {
export const destroyScope = (server, a, b, names) => {
let scopes = Object.keys(b.options.scopes);
server.route({
method: 'DELETE',
path: `${prefix}/${a._singular}/{aid}/${b._plural}/{scope}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}/{scope}`,
@error
async handler(request, reply) {
let where = _.omit(request.query, 'include');
const include = parseInclude(request);
const where = parseWhere(request);
for (const key of Object.keys(where)) {
try {
where[key] = JSON.parse(where[key]);
} catch (e) {
//
const base = await a.findOne({
where: {
id: request.params.aid
}
}
});
let list = await b.scope(request.params.scope).findAll({
const method = getMethod(base, names.b);
const list = await method({
scope: request.params.scope,
where,
include: {
model: a,
where: {
id: request.params.aid
}
}
include
});
await* list.map(instance => instance.destroy());
@ -256,24 +206,25 @@ export const destroyScope = (server, a, b) => {
});
}
export const update = (server, a, b) => {
export const update = (server, a, b, names) => {
server.route({
method: 'PUT',
path: `${prefix}/${a._singular}/{aid}/${b._plural}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.plural}`,
@error
async handler(request, reply) {
let list = await b.findOne({
include: {
model: a,
where: {
id: request.params.aid,
const include = parseInclude(request);
const where = parseWhere(request);
...request.query
}
const base = await a.findOne({
where: {
id: request.params.aid
}
});
const method = getMethod(base, names.b);
const list = await method({ where, include });
await* list.map(instance => instance.update(request.payload));
reply(list);

View File

@ -1,82 +1,87 @@
import joi from 'joi';
import error from '../error';
import _ from 'lodash';
import { parseInclude, parseWhere, getMethod } from '../utils';
let prefix;
export default (server, a, b, options) => {
export default (server, a, b, names, options) => {
prefix = options.prefix;
get(server, a, b);
create(server, a, b);
destroy(server, a, b);
update(server, a, b);
get(server, a, b, names);
create(server, a, b, names);
destroy(server, a, b, names);
update(server, a, b, names);
}
export const get = (server, a, b) => {
export const get = (server, a, b, names) => {
server.route({
method: 'GET',
path: `${prefix}/${a._singular}/{aid}/${b._singular}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}`,
@error
async handler(request, reply) {
let include = [];
if (request.query.include)
include = [request.models[request.query.include]];
const include = parseInclude(request);
const where = parseWhere(request);
let where = _.omit(request.query, 'include');
let [instance] = await b.findAll({
where,
include: include.concat({
model: a,
where: {
id: request.params.aid
}
})
const base = await a.findOne({
where: {
id: request.params.aid
}
});
const method = getMethod(base, names.b, false);
reply(instance);
const list = await method({ where, include, limit: 1 });
if (Array.isArray(list)) {
reply(list[0]);
} else {
reply(list);
}
}
})
}
export const create = (server, a, b) => {
export const create = (server, a, b, names) => {
server.route({
method: 'POST',
path: `${prefix}/${a._singular}/{id}/${b._singular}`,
path: `${prefix}/${names.a.singular}/{id}/${names.b.singular}`,
@error
async handler(request, reply) {
request.payload[a.name + 'Id'] = request.params.id;
let instance = await request.models[b.name].create(request.payload);
const base = await a.findOne({
where: {
id: request.params.id
}
});
const method = getMethod(base, names.b, false, 'create');
const instance = await method(request.payload);
reply(instance);
}
})
}
export const destroy = (server, a, b) => {
export const destroy = (server, a, b, names) => {
server.route({
method: 'DELETE',
path: `${prefix}/${a._singular}/{aid}/${b._singular}/{bid}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
@error
async handler(request, reply) {
let instance = await b.findOne({
where: {
id: request.params.bid
},
const include = parseInclude(request);
const where = parseWhere(request);
include: [{
model: a,
where: {
id: request.params.aid
}
}]
const base = await a.findOne({
where: {
id: request.params.aid
}
});
const method = getMethod(base, names.b, false);
const instance = await method({ where, include });
await instance.destroy();
reply(instance);
@ -84,26 +89,25 @@ export const destroy = (server, a, b) => {
})
}
export const update = (server, a, b) => {
export const update = (server, a, b, names) => {
server.route({
method: 'PUT',
path: `${prefix}/${a._singular}/{aid}/${b._singular}/{bid}`,
path: `${prefix}/${names.a.singular}/{aid}/${names.b.singular}/{bid}`,
@error
async handler(request, reply) {
let instance = await b.findOne({
where: {
id: request.params.bid
},
const include = parseInclude(request);
const where = parseWhere(request);
include: [{
model: a,
where: {
id: request.params.aid
}
}]
const base = await a.findOne({
where: {
id: request.params.aid
}
});
const method = getMethod(base, names.b, false);
const instance = await method({ where, include });
await instance.update(request.payload);
reply(instance);