|
| 1 | +import utils from '../utils' |
| 2 | +import dataTypes from './data_types' |
| 3 | + |
| 4 | +// Creates an object like |
| 5 | +// { |
| 6 | +// singulars: { |
| 7 | +// 'users': 'user' |
| 8 | +// }, |
| 9 | +// plurals: { |
| 10 | +// 'user': 'users' |
| 11 | +// }, |
| 12 | +// } |
| 13 | +const collectSingularsAndPlurals = function (dataTypes) { |
| 14 | + const singulars = {} |
| 15 | + const plurals = {} |
| 16 | + |
| 17 | + for (let key in dataTypes) { |
| 18 | + let type= dataTypes[key] |
| 19 | + if (utils.isObject(type)) { |
| 20 | + singulars[type.plural] = type.singular |
| 21 | + plurals[type.singular] = type.plural |
| 22 | + } |
| 23 | + } |
| 24 | + return {singulars, plurals} |
| 25 | +} |
| 26 | + |
| 27 | +const pluralsAndSingulars = collectSingularsAndPlurals(dataTypes) |
| 28 | + |
| 29 | +// Returns a singular name or the string without the last character |
| 30 | +const singular = function (plural) { |
| 31 | + if (pluralsAndSingulars.singulars[plural]) { return pluralsAndSingulars.singulars[plural] } |
| 32 | + console.error(`Singular not found for ${plural}, falling back.`) |
| 33 | + return plural.slice(0, plural.length - 1) |
| 34 | +} |
| 35 | + |
| 36 | +// Returns a plural name or the string with an ending 's" |
| 37 | +const plural = function (singular) { |
| 38 | + if (pluralsAndSingulars.plurals[singular]) { return pluralsAndSingulars.plurals[singular] } |
| 39 | + console.error(`Plural not found for ${singular}, falling back`) |
| 40 | + return `${singular}s` |
| 41 | +} |
| 42 | + |
| 43 | +const dispatchOneRelations = function (entity, dispatch, entityType) { |
| 44 | + const relations = dataTypes[entityType].relations |
| 45 | + let fieldName = '' |
| 46 | + let typeName = '' |
| 47 | + let foreignKey = '' |
| 48 | + |
| 49 | + for (const relation of relations.one) { |
| 50 | + // Is the relation defined as string or object ? |
| 51 | + if (utils.isObject(relation)) { |
| 52 | + fieldName = relation.field |
| 53 | + typeName = relation.type |
| 54 | + foreignKey = `${relation.field}_id` |
| 55 | + } else { |
| 56 | + fieldName = relation |
| 57 | + typeName = relation |
| 58 | + foreignKey = `${relation}_id` |
| 59 | + } |
| 60 | + |
| 61 | + // Check if the relation is present in the entity |
| 62 | + if ( |
| 63 | + utils.objectHasKey(entity, fieldName) && |
| 64 | + // Prevent dispatching entities with no Ids |
| 65 | + // (i.e.: an entity like { name: 'my tag' } with nothing else |
| 66 | + utils.objectHasKey(entity[fieldName], 'id') && |
| 67 | + entity[fieldName].id |
| 68 | + ) { |
| 69 | + // Check if the foreign_key exists and set it if necessary |
| 70 | + if (!utils.objectHasKey(entity, foreignKey)) { |
| 71 | + entity[foreignKey] = entity[fieldName].id |
| 72 | + } else { |
| 73 | + console.log(`fk ${foreignKey} exists`) |
| 74 | + } |
| 75 | + dispatch(`dispatchAndCommit${utils.camelize(typeName)}`, entity[fieldName]) |
| 76 | + } |
| 77 | + |
| 78 | + // Anyway, we delete the key in the parent |
| 79 | + delete entity[fieldName] |
| 80 | + } |
| 81 | + |
| 82 | + return entity |
| 83 | +} |
| 84 | + |
| 85 | +const dispatchManyRelations = function (entity, dispatch, entityType) { |
| 86 | + const relations = dataTypes[entityType].relations |
| 87 | + let fieldName = '' |
| 88 | + let typeName = '' |
| 89 | + |
| 90 | + for (const relation of relations.many) { |
| 91 | + // Case where the relation is an object |
| 92 | + if (utils.isObject(relation)) { |
| 93 | + fieldName = relation.field |
| 94 | + typeName = relation.model |
| 95 | + } else { |
| 96 | + fieldName = relation |
| 97 | + typeName = relation |
| 98 | + } |
| 99 | + if (utils.objectHasKey(entity, fieldName)) { |
| 100 | + const singularRelationName = singular(typeName) |
| 101 | + for (const subEntity in entity[fieldName]) { |
| 102 | + if (entity[fieldName].hasOwnProperty(subEntity)) { |
| 103 | + // Prevent dispatching entities with no Ids |
| 104 | + if (entity[fieldName][subEntity].id) { |
| 105 | + dispatch(`dispatchAndCommit${utils.camelize(singularRelationName)}`, entity[fieldName][subEntity]) |
| 106 | + } |
| 107 | + } |
| 108 | + } |
| 109 | + delete entity[fieldName] |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + return entity |
| 114 | +} |
| 115 | + |
| 116 | +const dispatchHABTMRelations = function (entity, dispatch, entityType) { |
| 117 | + const relations = dataTypes[entityType].relations |
| 118 | + let typeName = '' |
| 119 | + |
| 120 | + for (const relation of relations.habtm) { |
| 121 | + if (utils.objectHasKey(entity, relation.name)) { |
| 122 | + const fieldName = relation.name |
| 123 | + const fkList = [] |
| 124 | + const singularRelationName = singular(relation.name) |
| 125 | + for (const subEntity in entity[fieldName]) { |
| 126 | + // Here we have a sub-object |
| 127 | + if (entity[fieldName].hasOwnProperty(subEntity)) { |
| 128 | + // Prevent dispatching entities with no Ids |
| 129 | + if (entity[fieldName][subEntity].id) { |
| 130 | + fkList.push(entity[fieldName][subEntity].id) |
| 131 | + dispatch(`dispatchAndCommit${utils.camelize(singularRelationName)}`, entity[fieldName][subEntity]) |
| 132 | + } else if (entity[fieldName][subEntity].fk_id) { |
| 133 | + fkList.push(entity[fieldName][subEntity].fk_id) |
| 134 | + } else { |
| 135 | + console.warning('I can\'t process this entity', modelName, entity[fieldName][subEntity]) |
| 136 | + } |
| 137 | + } |
| 138 | + } |
| 139 | + entity[fieldName] = fkList |
| 140 | + } |
| 141 | + } |
| 142 | + if (relations.habtm.length > 0) { |
| 143 | + delete entity._matchingData |
| 144 | + } |
| 145 | + |
| 146 | + return entity |
| 147 | +} |
| 148 | + |
| 149 | +// Take an entity and dispatches the related data in corresponding modules |
| 150 | +export default function (entity, dispatch, entityType) { |
| 151 | + return new Promise((resolve, reject) => { |
| 152 | + let newEntity |
| 153 | + newEntity = dispatchOneRelations(entity, dispatch, entityType) |
| 154 | + newEntity = dispatchManyRelations(newEntity, dispatch, entityType) |
| 155 | + newEntity = dispatchHABTMRelations(newEntity, dispatch, entityType) |
| 156 | + |
| 157 | + resolve(newEntity) |
| 158 | + }) |
| 159 | +} |
0 commit comments