160 lines
4.4 KiB
JavaScript
Raw Normal View History

'use strict';
/**
* Module dependencies
*/
// Public node modules.
const _ = require('lodash');
/*
* Set of utils for models
*/
module.exports = {
/**
* Find relation nature with verbose
*/
getNature: function (association, key, models) {
const strapi = _.isUndefined(global['strapi']) && !_.isUndefined(models) ? _.set({}, 'models', models) : global['strapi'];
const types = {
current: '',
other: ''
};
if (association.hasOwnProperty('via') && association.hasOwnProperty('collection')) {
const relatedAttribute = strapi.models[association.collection].attributes[association.via];
types.current = 'collection';
if (relatedAttribute.hasOwnProperty('collection')) {
types.other = 'collection';
} else if (relatedAttribute.hasOwnProperty('model')) {
types.other = 'model';
}
} else if (association.hasOwnProperty('via') && association.hasOwnProperty('model')) {
types.current = 'modelD';
// We have to find if they are a model linked to this key
_.forIn(strapi.models, function (model) {
_.forIn(model.attributes, function (attribute) {
if (attribute.hasOwnProperty('via') && attribute.via === key && attribute.hasOwnProperty('collection')) {
types.other = 'collection';
// Break loop
return false;
} else if (attribute.hasOwnProperty('model')) {
types.other = 'model';
// Break loop
return false;
}
});
});
} else if (association.hasOwnProperty('model')) {
types.current = 'model';
// We have to find if they are a model linked to this key
_.forIn(strapi.models, function (model) {
_.forIn(model.attributes, function (attribute) {
if (attribute.hasOwnProperty('via') && attribute.via === key) {
if (attribute.hasOwnProperty('collection')) {
types.other = 'collection';
// Break loop
return false;
} else if (attribute.hasOwnProperty('model')) {
types.other = 'modelD';
// Break loop
return false;
}
}
});
});
}
if (types.current === 'modelD' && types.other === 'model') {
return {
nature: 'oneToOne',
verbose: 'belongsTo'
};
} else if (types.current === 'model' && types.other === 'modelD') {
return {
nature: 'oneToOne',
verbose: 'hasOne'
};
} else if (types.current === 'model' && types.other === 'collection') {
return {
nature: 'oneToMany',
verbose: 'belongsTo'
};
} else if (types.current === 'collection' && types.other === 'model') {
return {
nature: 'manyToOne',
verbose: 'hasMany'
};
} else if (types.current === 'collection' && types.other === 'collection') {
return {
nature: 'manyToMany',
verbose: 'belongsToMany'
};
} else if (types.current === 'model' && types.other === '') {
return {
nature: 'oneWay',
verbose: 'belongsTo'
};
}
return undefined;
},
/**
* Return ORM used for this collection.
*/
getORM: function (collectionIdentity) {
return _.get(strapi.models, collectionIdentity.toLowerCase() + '.orm');
},
/**
* Define associations key to models
*/
defineAssociations: function (model, definition, association, key) {
// Initialize associations object
definition.associations = [];
// Exclude non-relational attribute
if (!association.hasOwnProperty('collection') && !association.hasOwnProperty('model')) {
return undefined;
}
// Get relation nature
const infos = this.getNature(association, key);
// Build associations object
if (association.hasOwnProperty('collection')) {
definition.associations.push({
alias: key,
type: 'collection',
collection: association.collection,
via: association.via || undefined,
nature: infos.nature,
autoPopulate: _.get(association, 'autoPopulate') === true
});
} else if (association.hasOwnProperty('model')) {
definition.associations.push({
alias: key,
type: 'model',
model: association.model,
via: association.via || undefined,
nature: infos.nature,
autoPopulate: _.get(association, 'autoPopulate') === true
});
}
}
};