LoopBack supports polymorphic relations in which a model can belong to more than one other model, on a single association. For example, you might have a Picture model that belongs to either an Author model or a Reader model.
The examples below use three example models: Picture, Author, and Reader.
Do polymorphic relations add methods to the models as the standard relations do? If so, what?
HasMany
The usual options apply, for example: as: 'photos'
to specify a different relation name/accessor.
Author.hasMany(Picture, { polymorphic: 'imageable' }); Reader.hasMany(Picture, { polymorphic: { // alternative syntax as: 'imageable', // if not set, default to: reference foreignKey: 'imageableId', // defaults to 'as + Id' discriminator: 'imageableType' // defaults to 'as + Type' } });
BelongsTo
Because you define the related model dynamically, you cannot declare it up front. So instead of passing in the related model (name), you specify the name of the polymorphic relation.
Picture.belongsTo('imageable', { polymorphic: true }); // Alternatively, use an object for setup: Picture.belongsTo('imageable', { polymorphic: { foreignKey: 'imageableId', discriminator: 'imageableType' } });
HasAndBelongsToMany
This requires an explicit 'through' model, in this case: PictureLink
The relations Picture.belongsTo(PictureLink)
and Picture.belongsTo('imageable', { polymorphic: true });
will be setup automatically.
The same is true for the needed properties on PictureLink.
Author.hasAndBelongsToMany(Picture, { through: PictureLink, polymorphic: 'imageable' }); Reader.hasAndBelongsToMany(Picture, { through: PictureLink, polymorphic: 'imageable' }); // Optionally, define inverse hasMany relations (invert: true): Picture.hasMany(Author, { through: PictureLink, polymorphic: 'imageable', invert: true }); Picture.hasMany(Reader, { through: PictureLink, polymorphic: 'imageable', invert: true });
HasOne
As shown here, you can specify as: 'avatar'
to explicitly set the name of the relation. If not set, it defaults to the polymorphic name.
Picture.belongsTo('imageable', { polymorphic: true }); Author.hasOne(Picture, { as: 'avatar', polymorphic: 'imageable' }); Reader.hasOne(Picture, { polymorphic: { as: 'imageable' } });