diff --git a/packages/strapi-bookshelf/lib/index.js b/packages/strapi-bookshelf/lib/index.js index aa34012882..9f6a83c945 100755 --- a/packages/strapi-bookshelf/lib/index.js +++ b/packages/strapi-bookshelf/lib/index.js @@ -233,15 +233,8 @@ module.exports = function(strapi) { // Expose ORM functions through the `strapi.models` object. strapi.models[model] = _.assign(global[globalName], strapi.models[model]); - // Push model to strapi global variables. - strapi.bookshelf.collections[globalName.toLowerCase()] = global[ - globalName - ]; - // Push attributes to be aware of model schema. - strapi.bookshelf.collections[ - globalName.toLowerCase() - ]._attributes = definition.attributes; + strapi.models[model]._attributes = definition.attributes; loadedHook(); } catch (err) { diff --git a/packages/strapi-mongoose/lib/index.js b/packages/strapi-mongoose/lib/index.js index 9711382ffe..684b8ccf4a 100644 --- a/packages/strapi-mongoose/lib/index.js +++ b/packages/strapi-mongoose/lib/index.js @@ -147,8 +147,6 @@ module.exports = function (strapi) { // Push model to strapi global variables. collection = global[definition.globalName]; - console.log(collection.associations); - // Push attributes to be aware of model schema. strapi.models[model]._attributes = definition.attributes; } catch (err) { diff --git a/packages/strapi-plugin-content-manager/config/queries/bookshelf.js b/packages/strapi-plugin-content-manager/config/queries/bookshelf.js index 50dbaa36a9..d2451ff395 100644 --- a/packages/strapi-plugin-content-manager/config/queries/bookshelf.js +++ b/packages/strapi-plugin-content-manager/config/queries/bookshelf.js @@ -1,3 +1,5 @@ +const _ = require('lodash'); + module.exports = { find: async function (params) { return await this @@ -32,13 +34,136 @@ module.exports = { }, update: async function (params) { - return await this + const virtualFields = []; + const response = await module.exports.findOne.call(this, params); + + // Only update fields which are on this document. + const values = params.parseRelationships === false ? params.values : Object.keys(JSON.parse(JSON.stringify(params.values))).reduce((acc, current) => { + const association = this.associations.filter(x => x.alias === current)[0]; + const details = this._attributes[current]; + + if (_.get(this._attributes, `${current}.isVirtual`) !== true && _.isUndefined(association)) { + acc[current] = params.values[current]; + } else { + switch (association.nature) { + case 'oneToOne': + if (response[current] !== params.values[current]) { + const value = _.isNull(params.values[current]) ? response[current] : params.values; + + const recordId = _.isNull(params.values[current]) ? value[this.primaryKey] || value.id || value._id : value[current]; + + if (response[current] && _.isObject(response[current]) && response[current][this.primaryKey] !== value[current]) { + virtualFields.push( + strapi.query(details.collection || details.model).update({ + id: response[current][this.primaryKey], + values: { + [details.via]: null + }, + parseRelationships: false + }) + ); + } + + // Remove previous relationship asynchronously if it exists. + virtualFields.push( + strapi.query(details.model || details.collection).findOne({ id : recordId }) + .then(record => { + if (record && _.isObject(record[details.via])) { + return module.exports.update.call(this, { + id: record[details.via][this.primaryKey] || record[details.via].id, + values: { + [current]: null + }, + parseRelationships: false + }); + } + + return Promise.resolve(); + }) + ); + + // Update the record on the other side. + // When params.values[current] is null this means that we are removing the relation. + virtualFields.push(strapi.query(details.model || details.collection).update({ + id: recordId, + values: { + [details.via]: _.isNull(params.values[current]) ? null : value[this.primaryKey] || value.id || value._id + }, + parseRelationships: false + })); + + acc[current] = _.isNull(params.values[current]) ? null : value[current]; + } + + break; + case 'oneToMany': + case 'manyToOne': + case 'manyToMany': + if (details.dominant === true) { + acc[current] = params.values[current]; + } else if (response[current] && _.isArray(response[current]) && current !== 'id') { + // Records to add in the relation. + const toAdd = _.differenceWith(params.values[current], response[current], (a, b) => + a[this.primaryKey].toString() === b[this.primaryKey].toString() + ); + // Records to remove in the relation. + const toRemove = _.differenceWith(response[current], params.values[current], (a, b) => + a[this.primaryKey].toString() === b[this.primaryKey].toString() + ) + .filter(x => toAdd.find(y => x.id === y.id) === undefined); + + // Push the work into the flow process. + toAdd.forEach(value => { + if (association.nature === 'manyToMany' && !_.isArray(params.values[this.primaryKey])) { + value[details.via] = (value[details.via] || []).concat([params.values[this.primaryKey]]); + } else { + value[details.via] = params.values[this.primaryKey]; + } + + virtualFields.push(strapi.query(details.model || details.collection).addRelation({ + id: value[this.primaryKey] || value.id || value._id, + values: value, + foreignKey: current + })); + }); + + toRemove.forEach(value => { + if (association.nature === 'manyToMany' && !_.isArray(params.values[this.primaryKey])) { + value[details.via] = value[details.via].filter(x => x.toString() !== params.values[this.primaryKey].toString()); + } else { + value[details.via] = null; + } + + virtualFields.push(strapi.query(details.model || details.collection).removeRelation({ + id: value[this.primaryKey] || value.id || value._id, + values: value, + foreignKey: current + })); + }); + } else if (_.get(this._attributes, `${current}.isVirtual`) !== true) { + acc[current] = params.values[current]; + } + + break; + default: + } + } + + return acc; + }, {}); + + virtualFields.push(this .forge({ [this.primaryKey]: params[this.primaryKey] }) .save(params.values, { patch: true - }); + })); + + // Update virtuals fields. + const process = await Promise.all(virtualFields); + + return process[process.length - 1]; }, delete: async function (params) { diff --git a/packages/strapi-plugin-content-manager/config/queries/mongoose.js b/packages/strapi-plugin-content-manager/config/queries/mongoose.js index 4a0985239a..558dd3b9b9 100644 --- a/packages/strapi-plugin-content-manager/config/queries/mongoose.js +++ b/packages/strapi-plugin-content-manager/config/queries/mongoose.js @@ -34,10 +34,9 @@ module.exports = { return module.exports.update.call(this, { [this.primaryKey]: entry[this.primaryKey], - values: { - id: entry[this.primaryKey], - ...params.values - } + values: _.merge({ + id: entry[this.primaryKey] + }, params.values) }); }, diff --git a/packages/strapi-plugin-settings-manager/package.json b/packages/strapi-plugin-settings-manager/package.json index 3a9ee9e2fd..2d87df9d17 100644 --- a/packages/strapi-plugin-settings-manager/package.json +++ b/packages/strapi-plugin-settings-manager/package.json @@ -48,7 +48,7 @@ "plop": "^1.8.1", "prettier": "^1.7.0", "rimraf": "^2.6.2", - "strapi-helper-plugin": "file:../strapi-helper-plugin", + "strapi-helper-plugin": "3.0.0-alpha.5.5", "webpack": "^3.6.0" }, "author": { @@ -68,4 +68,4 @@ "npm": ">= 3.0.0" }, "license": "MIT" -} +} \ No newline at end of file diff --git a/packages/strapi-utils/package.json b/packages/strapi-utils/package.json index 32ce37facc..207856befb 100644 --- a/packages/strapi-utils/package.json +++ b/packages/strapi-utils/package.json @@ -45,4 +45,4 @@ "npm": ">= 5.3.0" }, "license": "MIT" -} +} \ No newline at end of file