mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-03 19:36:20 +00:00 
			
		
		
		
	[WIP] Polymorphic assocations
This commit is contained in:
		
							parent
							
								
									b90239b100
								
							
						
					
					
						commit
						824567de0d
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -135,7 +135,18 @@ module.exports = function (strapi) {
 | 
			
		||||
                  });
 | 
			
		||||
 | 
			
		||||
                  if (!plugin) {
 | 
			
		||||
                    global[definition.globalName] = instance.model(definition.globalName, collection.schema, definition.collectionName);
 | 
			
		||||
                    // Enhance schema with polymorphic relationships.
 | 
			
		||||
                    const morphs = _.pickBy(definition.loadedModel, model => {
 | 
			
		||||
                      return model.type === 'discriminator';
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    if (_.size(morphs) > 0) {
 | 
			
		||||
                      const morph = morphs[Object.keys(morphs)[0]];
 | 
			
		||||
 | 
			
		||||
                      global[definition.globalName] = global[morph.ref].discriminator(morph.discriminator, collection.schema);
 | 
			
		||||
                    } else {
 | 
			
		||||
                      global[definition.globalName] = instance.model(definition.globalName, collection.schema, definition.collectionName);
 | 
			
		||||
                    }
 | 
			
		||||
                  } else {
 | 
			
		||||
                    instance.model(definition.globalName, collection.schema, definition.collectionName);
 | 
			
		||||
                  }
 | 
			
		||||
@ -195,10 +206,23 @@ module.exports = function (strapi) {
 | 
			
		||||
              // Call this callback function after we are done parsing
 | 
			
		||||
              // all attributes for relationships-- see below.
 | 
			
		||||
              const done = _.after(_.size(definition.attributes), () => {
 | 
			
		||||
                // Generate schema without virtual populate
 | 
			
		||||
                _.set(strapi.config.hook.settings.mongoose, 'collections.' + mongooseUtils.toCollectionName(definition.globalName) + '.schema', new instance.Schema(_.omitBy(definition.loadedModel, model => {
 | 
			
		||||
                  return model.type === 'virtual';
 | 
			
		||||
                })));
 | 
			
		||||
                // Extract discriminator (morphTo side)
 | 
			
		||||
                const discriminators = _.pickBy(definition.loadedModel, model => {
 | 
			
		||||
                  return model.hasOwnProperty('discriminatorKey');
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                const options = {};
 | 
			
		||||
 | 
			
		||||
                if (_.size(discriminators) > 0) {
 | 
			
		||||
                  options.discriminatorKey = 'type';
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Generate schema without virtual populate & discriminators.
 | 
			
		||||
                let schema = new instance.Schema(_.omitBy(definition.loadedModel, model => {
 | 
			
		||||
                  return model.type === 'virtual' || model.type === 'discriminator' || model.hasOwnProperty('discriminatorKey');
 | 
			
		||||
                }), options);
 | 
			
		||||
 | 
			
		||||
                _.set(strapi.config.hook.settings.mongoose, 'collections.' + mongooseUtils.toCollectionName(definition.globalName) + '.schema', schema);
 | 
			
		||||
 | 
			
		||||
                loadedAttributes();
 | 
			
		||||
              });
 | 
			
		||||
@ -292,6 +316,22 @@ module.exports = function (strapi) {
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                  }
 | 
			
		||||
                  case 'morphOne': {
 | 
			
		||||
                    const discriminator = plugin ? `${plugin}_${model.toLowerCase()}` : model.toLowerCase();
 | 
			
		||||
                    const ref = details.plugin ? strapi.plugins[details.plugin].models[details.model].globalId : strapi.models[details.model].globalId;
 | 
			
		||||
 | 
			
		||||
                    definition.loadedModel[name] = {
 | 
			
		||||
                      type: 'discriminator',
 | 
			
		||||
                      ref,
 | 
			
		||||
                      discriminator
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                  }
 | 
			
		||||
                  case 'morphTo': {
 | 
			
		||||
                    definition.loadedModel[name] = {
 | 
			
		||||
                      discriminatorKey: 'kind'
 | 
			
		||||
                    };
 | 
			
		||||
                  }
 | 
			
		||||
                  default:
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,10 @@
 | 
			
		||||
      "via": "users",
 | 
			
		||||
      "plugin": "users-permissions",
 | 
			
		||||
      "configurable": false
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": {
 | 
			
		||||
      "model": "upload",
 | 
			
		||||
      "via": "related"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -94,6 +94,8 @@ module.exports = {
 | 
			
		||||
          types.other = 'collectionD';
 | 
			
		||||
        } else if (relatedAttribute.hasOwnProperty('model')) {
 | 
			
		||||
          types.other = 'model';
 | 
			
		||||
        } else if (relatedAttribute.hasOwnProperty('key')) {
 | 
			
		||||
          types.other = 'morphTo';
 | 
			
		||||
        }
 | 
			
		||||
      } else if (association.hasOwnProperty('via') && association.hasOwnProperty('model')) {
 | 
			
		||||
        types.current = 'modelD';
 | 
			
		||||
@ -111,6 +113,8 @@ module.exports = {
 | 
			
		||||
 | 
			
		||||
              // Break loop
 | 
			
		||||
              return false;
 | 
			
		||||
            } else if (attribute.hasOwnProperty('key')) {
 | 
			
		||||
              types.other = 'morphTo'; // MorphTo
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
@ -156,9 +160,26 @@ module.exports = {
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      } else if (association.hasOwnProperty('key')) {
 | 
			
		||||
        types.current = 'morphTo';
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (types.current === 'modelD' && types.other === 'model') {
 | 
			
		||||
      if (types.current === 'morphTo') {
 | 
			
		||||
        return {
 | 
			
		||||
          nature: 'morphTo',
 | 
			
		||||
          verbose: 'morphTo'
 | 
			
		||||
        };
 | 
			
		||||
      } else if (types.current === 'modelD' && types.other === 'morphTo') {
 | 
			
		||||
        return {
 | 
			
		||||
          nature: 'oneToOne',
 | 
			
		||||
          verbose: 'morphOne'
 | 
			
		||||
        };
 | 
			
		||||
      } else if (types.current === 'collection' && types.other === 'morphTo') {
 | 
			
		||||
        return {
 | 
			
		||||
          nature: 'oneToMany',
 | 
			
		||||
          verbose: 'morphMany'
 | 
			
		||||
        };
 | 
			
		||||
      } else if (types.current === 'modelD' && types.other === 'model') {
 | 
			
		||||
        return {
 | 
			
		||||
          nature: 'oneToOne',
 | 
			
		||||
          verbose: 'belongsTo'
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user