mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 07:33:17 +00:00
clone entity
This commit is contained in:
parent
4c310e5659
commit
76eb559466
@ -80,6 +80,10 @@ const createRepository = (uid, db) => {
|
||||
return db.entityManager.updateMany(uid, params);
|
||||
},
|
||||
|
||||
clone(id, params) {
|
||||
return db.entityManager.clone(uid, id, params);
|
||||
},
|
||||
|
||||
delete(params) {
|
||||
return db.entityManager.delete(uid, params);
|
||||
},
|
||||
|
||||
@ -1,26 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
isUndefined,
|
||||
castArray,
|
||||
compact,
|
||||
isNil,
|
||||
has,
|
||||
isString,
|
||||
isInteger,
|
||||
pick,
|
||||
isPlainObject,
|
||||
isEmpty,
|
||||
isArray,
|
||||
isNull,
|
||||
uniqWith,
|
||||
isEqual,
|
||||
differenceWith,
|
||||
isNumber,
|
||||
map,
|
||||
difference,
|
||||
differenceWith,
|
||||
flow,
|
||||
has,
|
||||
isArray,
|
||||
isEmpty,
|
||||
isEqual,
|
||||
isInteger,
|
||||
isNil,
|
||||
isNull,
|
||||
isNumber,
|
||||
isPlainObject,
|
||||
isString,
|
||||
isUndefined,
|
||||
map,
|
||||
mergeWith,
|
||||
omit,
|
||||
pick,
|
||||
uniqBy,
|
||||
uniqWith,
|
||||
} = require('lodash/fp');
|
||||
|
||||
const { mapAsync } = require('@strapi/utils');
|
||||
const types = require('../types');
|
||||
const { createField } = require('../fields');
|
||||
@ -28,6 +32,7 @@ const { createQueryBuilder } = require('../query');
|
||||
const { createRepository } = require('./entity-repository');
|
||||
const { deleteRelatedMorphOneRelationsAfterMorphToManyUpdate } = require('./morph-relations');
|
||||
const {
|
||||
isPolymorphic,
|
||||
isBidirectional,
|
||||
isAnyToOne,
|
||||
isOneToAny,
|
||||
@ -365,6 +370,63 @@ const createEntityManager = (db) => {
|
||||
return result;
|
||||
},
|
||||
|
||||
async clone(uid, cloneId, params = {}) {
|
||||
const states = await db.lifecycles.run('beforeCreate', uid, { params });
|
||||
|
||||
const metadata = db.metadata.get(uid);
|
||||
const { data } = params;
|
||||
|
||||
if (!isNil(data) && !isPlainObject(data)) {
|
||||
throw new Error('Create expects a data object');
|
||||
}
|
||||
|
||||
// TODO: Handle join columns?
|
||||
const entity = await this.findOne(uid, { where: { id: cloneId } });
|
||||
|
||||
const dataToInsert = flow(
|
||||
// Omit unwanted properties
|
||||
omit(['id', 'created_at', 'updated_at']),
|
||||
// Merge with provided data, override to null if data attribute is null
|
||||
mergeWith(params.data || {}, (a, b) => (b === null ? b : a)),
|
||||
// Process data with metadata
|
||||
(entity) => processData(metadata, entity, { withDefaults: true })
|
||||
)(entity);
|
||||
|
||||
const res = await this.createQueryBuilder(uid).insert(dataToInsert).execute();
|
||||
|
||||
const id = res[0].id || res[0];
|
||||
|
||||
// TODO: try strapi.db.transaction(method) instead of trx.get()
|
||||
const trx = await strapi.db.transaction();
|
||||
try {
|
||||
const cloneAttrs = Object.entries(metadata.attributes).reduce((acc, [attrName, attr]) => {
|
||||
if (attr.type === 'relation' && attr.joinTable && !attr.component) {
|
||||
acc[attrName] = true;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// How to get the relations of the clone entity ?
|
||||
await this.cloneRelations(uid, id, cloneId, { cloneAttrs, transaction: trx.get() });
|
||||
await this.updateRelations(uid, id, data, { transaction: trx.get() });
|
||||
await trx.commit();
|
||||
} catch (e) {
|
||||
await trx.rollback();
|
||||
await this.createQueryBuilder(uid).where({ id }).delete().execute();
|
||||
throw e;
|
||||
}
|
||||
|
||||
const result = await this.findOne(uid, {
|
||||
where: { id },
|
||||
select: params.select,
|
||||
populate: params.populate,
|
||||
});
|
||||
|
||||
await db.lifecycles.run('afterCreate', uid, { params, result }, states);
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
async delete(uid, params = {}) {
|
||||
const states = await db.lifecycles.run('beforeDelete', uid, { params });
|
||||
|
||||
@ -1203,13 +1265,17 @@ const createEntityManager = (db) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (isPolymorphic(attribute)) {
|
||||
// TODO: add support for cloning polymorphic relations
|
||||
return;
|
||||
}
|
||||
|
||||
if (attribute.joinColumn) {
|
||||
// TODO: add support for cloning oneToMany relations on the owning side
|
||||
return;
|
||||
}
|
||||
|
||||
if (!attribute.joinTable) {
|
||||
// TODO: add support for cloning polymorphic relations
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user