mirror of
https://github.com/strapi/strapi.git
synced 2025-08-26 01:35:56 +00:00
Merge branch 'develop' of github.com:strapi/strapi into ctm/repeatable-edit-view
This commit is contained in:
commit
fdb0f86fcc
@ -59,8 +59,8 @@
|
|||||||
"collection": "tag"
|
"collection": "tag"
|
||||||
},
|
},
|
||||||
"manyTags": {
|
"manyTags": {
|
||||||
"dominant": true,
|
|
||||||
"collection": "tag",
|
"collection": "tag",
|
||||||
|
"dominant": true,
|
||||||
"via": "linkedArticles"
|
"via": "linkedArticles"
|
||||||
},
|
},
|
||||||
"fb_cta": {
|
"fb_cta": {
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
},
|
},
|
||||||
"article": {
|
"article": {
|
||||||
"model": "article"
|
"model": "article"
|
||||||
|
},
|
||||||
|
"articles": {
|
||||||
|
"collection": "article"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -623,7 +623,8 @@ module.exports = ({ models, target, plugin = false }, ctx) => {
|
|||||||
} else {
|
} else {
|
||||||
options.withRelated = groupAttributes
|
options.withRelated = groupAttributes
|
||||||
.map(key => `${key}.slice`)
|
.map(key => `${key}.slice`)
|
||||||
.map(addPolymorphicRelated);
|
.map(addPolymorphicRelated)
|
||||||
|
.reduce((acc, paths) => acc.concat(paths), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.isFunction(target[model.toLowerCase()]['beforeFetchAll'])
|
return _.isFunction(target[model.toLowerCase()]['beforeFetchAll'])
|
||||||
|
@ -38,6 +38,13 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const wrapTransaction = (fn, { transacting } = {}) => {
|
||||||
|
const db = strapi.connections[model.connection];
|
||||||
|
|
||||||
|
if (transacting) return fn(transacting);
|
||||||
|
return db.transaction(trx => fn(trx));
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find one entry based on params
|
* Find one entry based on params
|
||||||
*/
|
*/
|
||||||
@ -60,12 +67,12 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
/**
|
/**
|
||||||
* Find multiple entries based on params
|
* Find multiple entries based on params
|
||||||
*/
|
*/
|
||||||
function find(params, populate) {
|
function find(params, populate, { transacting } = {}) {
|
||||||
const filters = convertRestQueryParams(params);
|
const filters = convertRestQueryParams(params);
|
||||||
|
|
||||||
return model
|
return model
|
||||||
.query(buildQuery({ model, filters }))
|
.query(buildQuery({ model, filters }))
|
||||||
.fetchAll({ withRelated: populate || defaultPopulate })
|
.fetchAll({ withRelated: populate || defaultPopulate, transacting })
|
||||||
.then(results => results.toJSON());
|
.then(results => results.toJSON());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +85,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
return model.query(buildQuery({ model, filters: { where } })).count();
|
return model.query(buildQuery({ model, filters: { where } })).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function create(values) {
|
async function create(values, { transacting } = {}) {
|
||||||
const relations = pickRelations(values);
|
const relations = pickRelations(values);
|
||||||
const data = selectAttributes(values);
|
const data = selectAttributes(values);
|
||||||
|
|
||||||
@ -89,14 +96,16 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
return entry;
|
return entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
const db = strapi.connections[model.connection];
|
const entry = await wrapTransaction(runCreate, { transacting });
|
||||||
const entry = await db.transaction(trx => runCreate(trx));
|
|
||||||
|
|
||||||
return model.updateRelations({ id: entry.id, values: relations });
|
return model.updateRelations(
|
||||||
|
{ id: entry.id, values: relations },
|
||||||
|
{ transacting }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function update(params, values) {
|
async function update(params, values, { transacting } = {}) {
|
||||||
const entry = await model.forge(params).fetch();
|
const entry = await model.forge(params).fetch({ transacting });
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
const err = new Error('entry.notFound');
|
const err = new Error('entry.notFound');
|
||||||
@ -121,20 +130,20 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
return updatedEntry;
|
return updatedEntry;
|
||||||
};
|
};
|
||||||
|
|
||||||
const db = strapi.connections[model.connection];
|
await wrapTransaction(runUpdate, { transacting });
|
||||||
await db.transaction(trx => runUpdate(trx));
|
|
||||||
|
|
||||||
if (Object.keys(relations).length > 0) {
|
if (Object.keys(relations).length > 0) {
|
||||||
return model.updateRelations(
|
return model.updateRelations(
|
||||||
Object.assign(params, { values: relations })
|
Object.assign(params, { values: relations }),
|
||||||
|
{ transacting }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await model.forge(params).fetch();
|
return await model.forge(params).fetch({ transacting });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteOne(params) {
|
async function deleteOne(params, { transacting } = {}) {
|
||||||
const entry = await model.forge(params).fetch();
|
const entry = await model.forge(params).fetch({ transacting });
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
const err = new Error('entry.notFound');
|
const err = new Error('entry.notFound');
|
||||||
@ -151,6 +160,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
case 'oneToManyMorph':
|
case 'oneToManyMorph':
|
||||||
values[association.alias] = null;
|
values[association.alias] = null;
|
||||||
break;
|
break;
|
||||||
|
case 'manyWay':
|
||||||
case 'oneToMany':
|
case 'oneToMany':
|
||||||
case 'manyToMany':
|
case 'manyToMany':
|
||||||
case 'manyToManyMorph':
|
case 'manyToManyMorph':
|
||||||
@ -160,25 +170,26 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await model.updateRelations({ ...params, values });
|
await model.updateRelations({ ...params, values }, { transacting });
|
||||||
|
|
||||||
const runDelete = async trx => {
|
const runDelete = async trx => {
|
||||||
await deleteGroups(entry, { transacting: trx });
|
await deleteGroups(entry, { transacting: trx });
|
||||||
await model.forge(params).destroy({ transacting: trx });
|
await model.forge(params).destroy({ transacting: trx, require: false });
|
||||||
return entry;
|
return entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
const db = strapi.connections[model.connection];
|
return wrapTransaction(runDelete, { transacting });
|
||||||
return db.transaction(trx => runDelete(trx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteMany(params) {
|
async function deleteMany(params, { transacting } = {}) {
|
||||||
const primaryKey = params[model.primaryKey] || params.id;
|
const primaryKey = params[model.primaryKey] || params.id;
|
||||||
|
|
||||||
if (primaryKey) return deleteOne(params);
|
if (primaryKey) return deleteOne(params, { transacting });
|
||||||
|
|
||||||
const entries = await find(params);
|
const entries = await find(params, null, { transacting });
|
||||||
return await Promise.all(entries.map(entry => deleteOne({ id: entry.id })));
|
return await Promise.all(
|
||||||
|
entries.map(entry => deleteOne({ id: entry.id }, { transacting }))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(params, populate) {
|
function search(params, populate) {
|
||||||
@ -210,7 +221,11 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function countSearch(params) {
|
function countSearch(params) {
|
||||||
return model.query(qb => buildSearchQuery(qb, model, params)).count();
|
return model
|
||||||
|
.query(qb => {
|
||||||
|
buildSearchQuery(qb, model, params);
|
||||||
|
})
|
||||||
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createGroups(entry, values, { transacting }) {
|
async function createGroups(entry, values, { transacting }) {
|
||||||
@ -221,14 +236,14 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
|
|
||||||
for (let key of groupKeys) {
|
for (let key of groupKeys) {
|
||||||
const attr = model.attributes[key];
|
const attr = model.attributes[key];
|
||||||
const { group, required = false, repeatable = true } = attr;
|
const { group, required = false, repeatable = false } = attr;
|
||||||
|
|
||||||
const groupModel = strapi.groups[group];
|
const groupModel = strapi.groups[group];
|
||||||
|
|
||||||
const createGroupAndLink = async ({ value, order }) => {
|
const createGroupAndLink = async ({ value, order }) => {
|
||||||
return groupModel
|
return strapi
|
||||||
.forge()
|
.query(groupModel.uid)
|
||||||
.save(value, { transacting })
|
.create(value, { transacting })
|
||||||
.then(group => {
|
.then(group => {
|
||||||
return joinModel.forge().save(
|
return joinModel.forge().save(
|
||||||
{
|
{
|
||||||
@ -278,7 +293,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
if (!_.has(values, key)) continue;
|
if (!_.has(values, key)) continue;
|
||||||
|
|
||||||
const attr = model.attributes[key];
|
const attr = model.attributes[key];
|
||||||
const { group, repeatable = true } = attr;
|
const { group, repeatable = false } = attr;
|
||||||
|
|
||||||
const groupModel = strapi.groups[group];
|
const groupModel = strapi.groups[group];
|
||||||
|
|
||||||
@ -287,9 +302,15 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
const updateOrCreateGroupAndLink = async ({ value, order }) => {
|
const updateOrCreateGroupAndLink = async ({ value, order }) => {
|
||||||
// check if value has an id then update else create
|
// check if value has an id then update else create
|
||||||
if (_.has(value, groupModel.primaryKey)) {
|
if (_.has(value, groupModel.primaryKey)) {
|
||||||
return groupModel
|
return strapi
|
||||||
.forge(value)
|
.query(groupModel.uid)
|
||||||
.save(value, { transacting, patch: true, require: false })
|
.update(
|
||||||
|
{
|
||||||
|
[groupModel.primaryKey]: value[groupModel.primaryKey],
|
||||||
|
},
|
||||||
|
value,
|
||||||
|
{ transacting }
|
||||||
|
)
|
||||||
.then(group => {
|
.then(group => {
|
||||||
return joinModel
|
return joinModel
|
||||||
.forge()
|
.forge()
|
||||||
@ -310,9 +331,9 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// create
|
// create
|
||||||
return groupModel
|
return strapi
|
||||||
.forge()
|
.query(groupModel.uid)
|
||||||
.save(value, { transacting })
|
.create(value, { transacting })
|
||||||
.then(group => {
|
.then(group => {
|
||||||
return joinModel.forge().save(
|
return joinModel.forge().save(
|
||||||
{
|
{
|
||||||
@ -367,7 +388,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
|
|
||||||
const idsToKeep = groupArr
|
const idsToKeep = groupArr
|
||||||
.filter(el => _.has(el, groupModel.primaryKey))
|
.filter(el => _.has(el, groupModel.primaryKey))
|
||||||
.map(el => el[groupModel.primaryKey]);
|
.map(el => el[groupModel.primaryKey].toString());
|
||||||
|
|
||||||
const allIds = await joinModel
|
const allIds = await joinModel
|
||||||
.forge()
|
.forge()
|
||||||
@ -379,7 +400,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
|
|
||||||
// verify the provided ids are realted to this entity.
|
// verify the provided ids are realted to this entity.
|
||||||
idsToKeep.forEach(id => {
|
idsToKeep.forEach(id => {
|
||||||
if (!allIds.includes(id.toString())) {
|
if (!allIds.includes(id)) {
|
||||||
const err = new Error(
|
const err = new Error(
|
||||||
`Some of the provided groups in ${key} are not related to the entity`
|
`Some of the provided groups in ${key} are not related to the entity`
|
||||||
);
|
);
|
||||||
@ -395,10 +416,12 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
.query(qb => qb.whereIn('slice_id', idsToDelete))
|
.query(qb => qb.whereIn('slice_id', idsToDelete))
|
||||||
.destroy({ transacting, require: false });
|
.destroy({ transacting, require: false });
|
||||||
|
|
||||||
await groupModel
|
await strapi
|
||||||
.forge()
|
.query(groupModel.uid)
|
||||||
.query(qb => qb.whereIn(groupModel.primaryKey, idsToDelete))
|
.delete(
|
||||||
.destroy({ transacting, require: false });
|
{ [`${groupModel.primaryKey}_in`]: idsToDelete },
|
||||||
|
{ transacting }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,10 +449,10 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
.fetchAll({ transacting })
|
.fetchAll({ transacting })
|
||||||
.map(el => el.get('slice_id'));
|
.map(el => el.get('slice_id'));
|
||||||
|
|
||||||
await groupModel
|
await strapi
|
||||||
.forge()
|
.query(groupModel.uid)
|
||||||
.query(qb => qb.whereIn(groupModel.primaryKey, ids))
|
.delete({ [`${groupModel.primaryKey}_in`]: ids }, { transacting });
|
||||||
.destroy({ transacting, require: false });
|
|
||||||
await joinModel
|
await joinModel
|
||||||
.forge()
|
.forge()
|
||||||
.query({
|
.query({
|
||||||
@ -497,13 +520,13 @@ const buildSearchQuery = (qb, model, params) => {
|
|||||||
|
|
||||||
if (!_.isNaN(_.toNumber(query))) {
|
if (!_.isNaN(_.toNumber(query))) {
|
||||||
searchInt.forEach(attribute => {
|
searchInt.forEach(attribute => {
|
||||||
qb.orWhereRaw(attribute, _.toNumber(query));
|
qb.orWhere(attribute, _.toNumber(query));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query === 'true' || query === 'false') {
|
if (query === 'true' || query === 'false') {
|
||||||
searchBool.forEach(attribute => {
|
searchBool.forEach(attribute => {
|
||||||
qb.orWhereRaw(attribute, _.toNumber(query === 'true'));
|
qb.orWhere(attribute, _.toNumber(query === 'true'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +46,11 @@ const getModel = (model, plugin) => {
|
|||||||
const removeUndefinedKeys = obj => _.pickBy(obj, _.negate(_.isUndefined));
|
const removeUndefinedKeys = obj => _.pickBy(obj, _.negate(_.isUndefined));
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
findOne: async function(params, populate) {
|
async findOne(params, populate, { transacting } = {}) {
|
||||||
const record = await this.forge({
|
const record = await this.forge({
|
||||||
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey),
|
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey),
|
||||||
}).fetch({
|
}).fetch({
|
||||||
|
transacting,
|
||||||
withRelated: populate || this.associations.map(x => x.alias),
|
withRelated: populate || this.associations.map(x => x.alias),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -70,7 +71,9 @@ module.exports = {
|
|||||||
this.primaryKey
|
this.primaryKey
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.fetchAll();
|
.fetchAll({
|
||||||
|
transacting,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const related = await Promise.all(arrayOfPromises);
|
const related = await Promise.all(arrayOfPromises);
|
||||||
@ -83,10 +86,12 @@ module.exports = {
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
update: async function(params) {
|
async update(params, { transacting } = {}) {
|
||||||
const relationUpdates = [];
|
const relationUpdates = [];
|
||||||
const primaryKeyValue = getValuePrimaryKey(params, this.primaryKey);
|
const primaryKeyValue = getValuePrimaryKey(params, this.primaryKey);
|
||||||
const response = await module.exports.findOne.call(this, params);
|
const response = await module.exports.findOne.call(this, params, null, {
|
||||||
|
transacting,
|
||||||
|
});
|
||||||
|
|
||||||
// Only update fields which are on this document.
|
// Only update fields which are on this document.
|
||||||
const values =
|
const values =
|
||||||
@ -129,7 +134,12 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
.save(
|
.save(
|
||||||
{ [details.via]: null },
|
{ [details.via]: null },
|
||||||
{ method: 'update', patch: true, require: false }
|
{
|
||||||
|
method: 'update',
|
||||||
|
patch: true,
|
||||||
|
require: false,
|
||||||
|
transacting,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
relationUpdates.push(updatePromise);
|
relationUpdates.push(updatePromise);
|
||||||
@ -140,14 +150,24 @@ module.exports = {
|
|||||||
const updateLink = this.where({ [current]: property })
|
const updateLink = this.where({ [current]: property })
|
||||||
.save(
|
.save(
|
||||||
{ [current]: null },
|
{ [current]: null },
|
||||||
{ method: 'update', patch: true, require: false }
|
{
|
||||||
|
method: 'update',
|
||||||
|
patch: true,
|
||||||
|
require: false,
|
||||||
|
transacting,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return assocModel
|
return assocModel
|
||||||
.where({ [this.primaryKey]: property })
|
.where({ [this.primaryKey]: property })
|
||||||
.save(
|
.save(
|
||||||
{ [details.via]: primaryKeyValue },
|
{ [details.via]: primaryKeyValue },
|
||||||
{ method: 'update', patch: true, require: false }
|
{
|
||||||
|
method: 'update',
|
||||||
|
patch: true,
|
||||||
|
require: false,
|
||||||
|
transacting,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -179,7 +199,12 @@ module.exports = {
|
|||||||
)
|
)
|
||||||
.save(
|
.save(
|
||||||
{ [details.via]: null },
|
{ [details.via]: null },
|
||||||
{ method: 'update', patch: true, require: false }
|
{
|
||||||
|
method: 'update',
|
||||||
|
patch: true,
|
||||||
|
require: false,
|
||||||
|
transacting,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return assocModel
|
return assocModel
|
||||||
@ -190,7 +215,12 @@ module.exports = {
|
|||||||
)
|
)
|
||||||
.save(
|
.save(
|
||||||
{ [details.via]: primaryKeyValue },
|
{ [details.via]: primaryKeyValue },
|
||||||
{ method: 'update', patch: true, require: false }
|
{
|
||||||
|
method: 'update',
|
||||||
|
patch: true,
|
||||||
|
require: false,
|
||||||
|
transacting,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -221,9 +251,10 @@ module.exports = {
|
|||||||
const collection = this.forge({
|
const collection = this.forge({
|
||||||
[this.primaryKey]: primaryKeyValue,
|
[this.primaryKey]: primaryKeyValue,
|
||||||
})[association.alias]();
|
})[association.alias]();
|
||||||
|
|
||||||
const updatePromise = collection
|
const updatePromise = collection
|
||||||
.detach(toRemove)
|
.detach(toRemove, { transacting })
|
||||||
.then(() => collection.attach(toAdd));
|
.then(() => collection.attach(toAdd, { transacting }));
|
||||||
|
|
||||||
relationUpdates.push(updatePromise);
|
relationUpdates.push(updatePromise);
|
||||||
return acc;
|
return acc;
|
||||||
@ -242,31 +273,43 @@ module.exports = {
|
|||||||
if (association.nature === 'manyMorphToOne') {
|
if (association.nature === 'manyMorphToOne') {
|
||||||
relationUpdates.push(
|
relationUpdates.push(
|
||||||
module.exports.removeRelationMorph
|
module.exports.removeRelationMorph
|
||||||
.call(this, {
|
.call(
|
||||||
alias: association.alias,
|
this,
|
||||||
ref: model.collectionName,
|
{
|
||||||
refId: obj.refId,
|
|
||||||
field: obj.field,
|
|
||||||
})
|
|
||||||
.then(() =>
|
|
||||||
module.exports.addRelationMorph.call(this, {
|
|
||||||
id: response[this.primaryKey],
|
|
||||||
alias: association.alias,
|
alias: association.alias,
|
||||||
ref: model.collectionName,
|
ref: model.collectionName,
|
||||||
refId: obj.refId,
|
refId: obj.refId,
|
||||||
field: obj.field,
|
field: obj.field,
|
||||||
})
|
},
|
||||||
|
{ transacting }
|
||||||
|
)
|
||||||
|
.then(() =>
|
||||||
|
module.exports.addRelationMorph.call(
|
||||||
|
this,
|
||||||
|
{
|
||||||
|
id: response[this.primaryKey],
|
||||||
|
alias: association.alias,
|
||||||
|
ref: model.collectionName,
|
||||||
|
refId: obj.refId,
|
||||||
|
field: obj.field,
|
||||||
|
},
|
||||||
|
{ transacting }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
relationUpdates.push(
|
relationUpdates.push(
|
||||||
module.exports.addRelationMorph.call(this, {
|
module.exports.addRelationMorph.call(
|
||||||
id: response[this.primaryKey],
|
this,
|
||||||
alias: association.alias,
|
{
|
||||||
ref: model.collectionName,
|
id: response[this.primaryKey],
|
||||||
refId: obj.refId,
|
alias: association.alias,
|
||||||
field: obj.field,
|
ref: model.collectionName,
|
||||||
})
|
refId: obj.refId,
|
||||||
|
field: obj.field,
|
||||||
|
},
|
||||||
|
{ transacting }
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -293,26 +336,34 @@ module.exports = {
|
|||||||
|
|
||||||
toAdd.forEach(id => {
|
toAdd.forEach(id => {
|
||||||
relationUpdates.push(
|
relationUpdates.push(
|
||||||
module.exports.addRelationMorph.call(model, {
|
module.exports.addRelationMorph.call(
|
||||||
id,
|
model,
|
||||||
alias: association.via,
|
{
|
||||||
ref: this.collectionName,
|
id,
|
||||||
refId: response.id,
|
alias: association.via,
|
||||||
field: association.alias,
|
ref: this.collectionName,
|
||||||
})
|
refId: response.id,
|
||||||
|
field: association.alias,
|
||||||
|
},
|
||||||
|
{ transacting }
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the relational array.
|
// Update the relational array.
|
||||||
toRemove.forEach(id => {
|
toRemove.forEach(id => {
|
||||||
relationUpdates.push(
|
relationUpdates.push(
|
||||||
module.exports.removeRelationMorph.call(model, {
|
module.exports.removeRelationMorph.call(
|
||||||
id,
|
model,
|
||||||
alias: association.via,
|
{
|
||||||
ref: this.collectionName,
|
id,
|
||||||
refId: response.id,
|
alias: association.via,
|
||||||
field: association.alias,
|
ref: this.collectionName,
|
||||||
})
|
refId: response.id,
|
||||||
|
field: association.alias,
|
||||||
|
},
|
||||||
|
{ transacting }
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -336,17 +387,19 @@ module.exports = {
|
|||||||
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey),
|
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey),
|
||||||
}).save(values, {
|
}).save(values, {
|
||||||
patch: true,
|
patch: true,
|
||||||
|
transacting,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.forge({
|
return await this.forge({
|
||||||
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey),
|
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey),
|
||||||
}).fetch({
|
}).fetch({
|
||||||
|
transacting,
|
||||||
withRelated: this.associations.map(x => x.alias),
|
withRelated: this.associations.map(x => x.alias),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addRelationMorph: async function(params) {
|
async addRelationMorph(params, { transacting } = {}) {
|
||||||
const record = await this.morph
|
const record = await this.morph
|
||||||
.forge()
|
.forge()
|
||||||
.where({
|
.where({
|
||||||
@ -356,6 +409,7 @@ module.exports = {
|
|||||||
field: params.field,
|
field: params.field,
|
||||||
})
|
})
|
||||||
.fetch({
|
.fetch({
|
||||||
|
transacting,
|
||||||
withRelated: this.associations.map(x => x.alias),
|
withRelated: this.associations.map(x => x.alias),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -372,10 +426,10 @@ module.exports = {
|
|||||||
[`${params.alias}_type`]: params.ref,
|
[`${params.alias}_type`]: params.ref,
|
||||||
field: params.field,
|
field: params.field,
|
||||||
})
|
})
|
||||||
.save();
|
.save(null, { transacting });
|
||||||
},
|
},
|
||||||
|
|
||||||
removeRelationMorph: async function(params) {
|
async removeRelationMorph(params, { transacting } = {}) {
|
||||||
return await this.morph
|
return await this.morph
|
||||||
.forge()
|
.forge()
|
||||||
.where(
|
.where(
|
||||||
@ -391,6 +445,7 @@ module.exports = {
|
|||||||
)
|
)
|
||||||
.destroy({
|
.destroy({
|
||||||
require: false,
|
require: false,
|
||||||
|
transacting,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -38,7 +38,7 @@ module.exports = ({ model, modelKey, strapi }) => {
|
|||||||
|
|
||||||
for (let key of groupKeys) {
|
for (let key of groupKeys) {
|
||||||
const attr = model.attributes[key];
|
const attr = model.attributes[key];
|
||||||
const { group, required = false, repeatable = true } = attr;
|
const { group, required = false, repeatable = false } = attr;
|
||||||
|
|
||||||
const groupModel = strapi.groups[group];
|
const groupModel = strapi.groups[group];
|
||||||
|
|
||||||
@ -55,23 +55,25 @@ module.exports = ({ model, modelKey, strapi }) => {
|
|||||||
if (repeatable === true) {
|
if (repeatable === true) {
|
||||||
validateRepeatableInput(groupValue, { key, ...attr });
|
validateRepeatableInput(groupValue, { key, ...attr });
|
||||||
const groups = await Promise.all(
|
const groups = await Promise.all(
|
||||||
groupValue.map(value => groupModel.create(value))
|
groupValue.map(value => {
|
||||||
|
return strapi.query(group).create(value);
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const groupsArr = groups.map(group => ({
|
const groupsArr = groups.map(groupEntry => ({
|
||||||
kind: groupModel.globalId,
|
kind: groupModel.globalId,
|
||||||
ref: group,
|
ref: groupEntry,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
entry[key] = groupsArr;
|
entry[key] = groupsArr;
|
||||||
await entry.save();
|
await entry.save();
|
||||||
} else {
|
} else {
|
||||||
validateNonRepeatableInput(groupValue, { key, ...attr });
|
validateNonRepeatableInput(groupValue, { key, ...attr });
|
||||||
const group = await groupModel.create(groupValue);
|
const groupEntry = await strapi.query(group).create(groupValue);
|
||||||
entry[key] = [
|
entry[key] = [
|
||||||
{
|
{
|
||||||
kind: groupModel.globalId,
|
kind: groupModel.globalId,
|
||||||
ref: group,
|
ref: groupEntry,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
await entry.save();
|
await entry.save();
|
||||||
@ -87,7 +89,7 @@ module.exports = ({ model, modelKey, strapi }) => {
|
|||||||
if (!_.has(values, key)) continue;
|
if (!_.has(values, key)) continue;
|
||||||
|
|
||||||
const attr = model.attributes[key];
|
const attr = model.attributes[key];
|
||||||
const { group, repeatable = true } = attr;
|
const { group, repeatable = false } = attr;
|
||||||
|
|
||||||
const groupModel = strapi.groups[group];
|
const groupModel = strapi.groups[group];
|
||||||
const groupValue = values[key];
|
const groupValue = values[key];
|
||||||
@ -95,15 +97,14 @@ module.exports = ({ model, modelKey, strapi }) => {
|
|||||||
const updateOrCreateGroup = async value => {
|
const updateOrCreateGroup = async value => {
|
||||||
// check if value has an id then update else create
|
// check if value has an id then update else create
|
||||||
if (hasPK(value)) {
|
if (hasPK(value)) {
|
||||||
return groupModel.findOneAndUpdate(
|
return strapi.query(group).update(
|
||||||
{
|
{
|
||||||
[model.primaryKey]: getPK(value),
|
[model.primaryKey]: getPK(value),
|
||||||
},
|
},
|
||||||
value,
|
value
|
||||||
{ new: true }
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return groupModel.create(value);
|
return strapi.query(group).create(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (repeatable === true) {
|
if (repeatable === true) {
|
||||||
@ -162,7 +163,9 @@ module.exports = ({ model, modelKey, strapi }) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (idsToDelete.length > 0) {
|
if (idsToDelete.length > 0) {
|
||||||
await groupModel.deleteMany({ [model.primaryKey]: { $in: idsToDelete } });
|
await strapi
|
||||||
|
.query(groupModel.uid)
|
||||||
|
.delete({ [`${model.primaryKey}_in`]: idsToDelete });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,9 +178,10 @@ module.exports = ({ model, modelKey, strapi }) => {
|
|||||||
const groupModel = strapi.groups[group];
|
const groupModel = strapi.groups[group];
|
||||||
|
|
||||||
if (Array.isArray(entry[key]) && entry[key].length > 0) {
|
if (Array.isArray(entry[key]) && entry[key].length > 0) {
|
||||||
await groupModel.deleteMany({
|
const idsToDelete = entry[key].map(el => el.ref);
|
||||||
[model.primaryKey]: { $in: entry[key].map(el => el.ref) },
|
await strapi
|
||||||
});
|
.query(groupModel.uid)
|
||||||
|
.delete({ [`${model.primaryKey}_in`]: idsToDelete });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,17 +208,9 @@ module.exports = {
|
|||||||
case 'manyMorphToOne':
|
case 'manyMorphToOne':
|
||||||
// Update the relational array.
|
// Update the relational array.
|
||||||
acc[current] = property.map(obj => {
|
acc[current] = property.map(obj => {
|
||||||
const globalId =
|
|
||||||
obj.source && obj.source !== 'content-manager'
|
|
||||||
? strapi.plugins[obj.source].models[_.toLower(obj.ref)]
|
|
||||||
.globalId
|
|
||||||
: strapi.models[_.toLower(obj.ref)].globalId;
|
|
||||||
|
|
||||||
// Define the object stored in database.
|
|
||||||
// The shape is this object is defined by the strapi-hook-mongoose connector.
|
|
||||||
return {
|
return {
|
||||||
ref: obj.refId,
|
ref: obj.refId,
|
||||||
kind: globalId,
|
kind: obj.ref,
|
||||||
[association.filter]: obj.field,
|
[association.filter]: obj.field,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@ module.exports = {
|
|||||||
strapi.plugins['content-manager'].services['contentmanager'];
|
strapi.plugins['content-manager'].services['contentmanager'];
|
||||||
|
|
||||||
let entities = [];
|
let entities = [];
|
||||||
if (!_.isEmpty(ctx.request.query._q)) {
|
if (_.has(ctx.request.query, '_q')) {
|
||||||
entities = await contentManagerService.search(
|
entities = await contentManagerService.search(
|
||||||
ctx.params,
|
ctx.params,
|
||||||
ctx.request.query
|
ctx.request.query
|
||||||
@ -51,7 +51,7 @@ module.exports = {
|
|||||||
strapi.plugins['content-manager'].services['contentmanager'];
|
strapi.plugins['content-manager'].services['contentmanager'];
|
||||||
|
|
||||||
let count;
|
let count;
|
||||||
if (!_.isEmpty(ctx.request.query._q)) {
|
if (_.has(ctx.request.query, '_q')) {
|
||||||
count = await contentManagerService.countSearch(
|
count = await contentManagerService.countSearch(
|
||||||
ctx.params,
|
ctx.params,
|
||||||
ctx.request.query
|
ctx.request.query
|
||||||
|
@ -127,23 +127,15 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
search(params, query) {
|
search(params, query) {
|
||||||
const { limit, skip, sort, source, _q, populate = [] } = query; // eslint-disable-line no-unused-vars
|
const { model } = params;
|
||||||
const filters = strapi.utils.models.convertParams(params.model, query);
|
const { source } = query;
|
||||||
|
|
||||||
// Find entries using `queries` system
|
return strapi.query(model, source).search(query);
|
||||||
return strapi.query(params.model, source).search(
|
|
||||||
{
|
|
||||||
limit: limit || filters.limit,
|
|
||||||
skip: skip || filters.start || 0,
|
|
||||||
sort: sort || filters.sort,
|
|
||||||
search: _q,
|
|
||||||
},
|
|
||||||
populate
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
countSearch(params, query) {
|
countSearch(params, query) {
|
||||||
|
const { model } = params;
|
||||||
const { source, _q } = query;
|
const { source, _q } = query;
|
||||||
return strapi.query(params.model, source).countSearch({ search: _q });
|
return strapi.query(model, source).countSearch({ _q });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -105,4 +105,15 @@ module.exports = {
|
|||||||
);
|
);
|
||||||
return getModel(uid);
|
return getModel(uid);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async updateUID({ oldUID, newUID, source }) {
|
||||||
|
const oldKey = uidToStoreKey({ uid: oldUID, source });
|
||||||
|
const newKey = uidToStoreKey({ uid: newUID, source });
|
||||||
|
|
||||||
|
await storeUtils.setModelConfiguration(oldKey, {
|
||||||
|
uid: oldUID,
|
||||||
|
});
|
||||||
|
|
||||||
|
return storeUtils.moveKey(oldKey, newKey);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -29,4 +29,16 @@ module.exports = {
|
|||||||
const storeKey = uidToStoreKey(uid);
|
const storeKey = uidToStoreKey(uid);
|
||||||
return storeUtils.deleteKey(storeKey);
|
return storeUtils.deleteKey(storeKey);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async updateUID(oldUID, newUID) {
|
||||||
|
const oldKey = uidToStoreKey(oldUID);
|
||||||
|
const newKey = uidToStoreKey(newUID);
|
||||||
|
|
||||||
|
await storeUtils.setModelConfiguration(oldKey, {
|
||||||
|
uid: oldUID,
|
||||||
|
isGroup: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return storeUtils.moveKey(oldKey, newKey);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -89,6 +89,16 @@ function findByKeyQuery({ model }, key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const findByKey = key => strapi.query('core_store').custom(findByKeyQuery)(key);
|
const findByKey = key => strapi.query('core_store').custom(findByKeyQuery)(key);
|
||||||
|
const moveKey = (oldKey, newKey) => {
|
||||||
|
return strapi.query('core_store').update(
|
||||||
|
{
|
||||||
|
key: `plugin_content_manager_configuration_${oldKey}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `plugin_content_manager_configuration_${newKey}`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getAllConfigurations = () =>
|
const getAllConfigurations = () =>
|
||||||
findByKey('plugin_content_manager_configuration');
|
findByKey('plugin_content_manager_configuration');
|
||||||
@ -103,5 +113,6 @@ module.exports = {
|
|||||||
setModelConfiguration,
|
setModelConfiguration,
|
||||||
|
|
||||||
deleteKey,
|
deleteKey,
|
||||||
|
moveKey,
|
||||||
keys,
|
keys,
|
||||||
};
|
};
|
||||||
|
@ -220,8 +220,8 @@ module.exports = {
|
|||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
modelJSON.connection = connection;
|
modelJSON.connection = connection || modelJSON.connection;
|
||||||
modelJSON.collectionName = collectionName;
|
modelJSON.collectionName = collectionName || modelJSON.collectionName;
|
||||||
modelJSON.info = {
|
modelJSON.info = {
|
||||||
name,
|
name,
|
||||||
description: _description,
|
description: _description,
|
||||||
@ -256,6 +256,20 @@ module.exports = {
|
|||||||
if (!_.isEmpty(removeModelErrors)) {
|
if (!_.isEmpty(removeModelErrors)) {
|
||||||
return ctx.badRequest(null, [{ messages: removeModelErrors }]);
|
return ctx.badRequest(null, [{ messages: removeModelErrors }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
_.has(strapi.plugins, ['content-manager', 'services', 'contenttypes'])
|
||||||
|
) {
|
||||||
|
await _.get(strapi.plugins, [
|
||||||
|
'content-manager',
|
||||||
|
'services',
|
||||||
|
'contenttypes',
|
||||||
|
]).updateUID({
|
||||||
|
oldUID: model,
|
||||||
|
newUID: name.toLowerCase(),
|
||||||
|
source: plugin,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -116,15 +116,34 @@ async function createGroup(uid, infos) {
|
|||||||
* @param {Object} infos
|
* @param {Object} infos
|
||||||
*/
|
*/
|
||||||
async function updateGroup(group, infos) {
|
async function updateGroup(group, infos) {
|
||||||
const { uid } = group;
|
const { uid, schema: oldSchema } = group;
|
||||||
|
|
||||||
const newUid = createGroupUID(infos.name);
|
// don't update collectionName if not provided
|
||||||
if (uid !== newUid) {
|
const updatedSchema = {
|
||||||
|
info: {
|
||||||
|
name: infos.name || oldSchema.name,
|
||||||
|
description: infos.description || oldSchema.description,
|
||||||
|
},
|
||||||
|
connection: infos.connection || oldSchema.connection,
|
||||||
|
collectionName: infos.collectionName || oldSchema.collectionName,
|
||||||
|
attributes: convertAttributes(infos.attributes),
|
||||||
|
};
|
||||||
|
|
||||||
|
const newUID = createGroupUID(infos.name);
|
||||||
|
if (uid !== newUID) {
|
||||||
await deleteSchema(uid);
|
await deleteSchema(uid);
|
||||||
return createGroup(newUid, infos);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedSchema = { ...group.schema, ...createSchema(uid, infos) };
|
if (_.has(strapi.plugins, ['content-manager', 'services', 'groups'])) {
|
||||||
|
await _.get(strapi.plugins, [
|
||||||
|
'content-manager',
|
||||||
|
'services',
|
||||||
|
'groups',
|
||||||
|
]).updateUID(uid, newUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeSchema(newUID, updatedSchema);
|
||||||
|
return { uid: newUID };
|
||||||
|
}
|
||||||
|
|
||||||
await writeSchema(uid, updatedSchema);
|
await writeSchema(uid, updatedSchema);
|
||||||
return { uid };
|
return { uid };
|
||||||
@ -137,7 +156,11 @@ async function updateGroup(group, infos) {
|
|||||||
const createSchema = (uid, infos) => {
|
const createSchema = (uid, infos) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
connection = 'default',
|
connection = _.get(
|
||||||
|
strapi,
|
||||||
|
['config', 'currentEnvironment', 'database', 'defaultConnection'],
|
||||||
|
'default'
|
||||||
|
),
|
||||||
description = '',
|
description = '',
|
||||||
collectionName,
|
collectionName,
|
||||||
attributes,
|
attributes,
|
||||||
@ -149,7 +172,7 @@ const createSchema = (uid, infos) => {
|
|||||||
description,
|
description,
|
||||||
},
|
},
|
||||||
connection,
|
connection,
|
||||||
collectionName: collectionName || `groups_${pluralize(uid)}`,
|
collectionName: collectionName || `groups_${pluralize(uid).toLowerCase()}`,
|
||||||
attributes: convertAttributes(attributes),
|
attributes: convertAttributes(attributes),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,16 @@ describe('Group Service', () => {
|
|||||||
attributes: {},
|
attributes: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
global.strapi = {
|
||||||
|
config: {
|
||||||
|
defaultEnvironment: {
|
||||||
|
database: {
|
||||||
|
defaultConnection: 'default',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const expected = {
|
const expected = {
|
||||||
info: {
|
info: {
|
||||||
name: 'Some name',
|
name: 'Some name',
|
||||||
|
@ -188,7 +188,7 @@ module.exports = {
|
|||||||
.findOne({ id: roleID }, ['users', 'permissions']);
|
.findOne({ id: roleID }, ['users', 'permissions']);
|
||||||
|
|
||||||
if (!role) {
|
if (!role) {
|
||||||
throw new Error('Cannot found this role');
|
throw new Error('Cannot find this role');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group by `type`.
|
// Group by `type`.
|
||||||
|
1
packages/strapi/lib/core/bootstrap.js
vendored
1
packages/strapi/lib/core/bootstrap.js
vendored
@ -51,6 +51,7 @@ module.exports = function(strapi) {
|
|||||||
throw new Error(`Group ${key} is missing a collectionName attribute`);
|
throw new Error(`Group ${key} is missing a collectionName attribute`);
|
||||||
|
|
||||||
return Object.assign(group, {
|
return Object.assign(group, {
|
||||||
|
uid: key,
|
||||||
modelType: 'group',
|
modelType: 'group',
|
||||||
globalId: group.globalId || _.upperFirst(_.camelCase(`group_${key}`)),
|
globalId: group.globalId || _.upperFirst(_.camelCase(`group_${key}`)),
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user