2019-06-03 21:00:03 +02:00
'use strict' ;
const _ = require ( 'lodash' ) ;
2019-07-05 17:17:39 +02:00
const { singular } = require ( 'pluralize' ) ;
2019-06-03 21:00:03 +02:00
const utilsModels = require ( 'strapi-utils' ) . models ;
const relations = require ( './relations' ) ;
2020-07-27 20:26:56 +02:00
const buildDatabaseSchema = require ( './build-database-schema' ) ;
2019-07-16 18:05:24 +02:00
const {
2019-10-22 18:01:03 +02:00
createComponentJoinTables ,
createComponentModels ,
} = require ( './generate-component-relations' ) ;
2019-12-03 11:27:15 +01:00
const { createParser } = require ( './parser' ) ;
const { createFormatter } = require ( './formatter' ) ;
2019-06-03 21:00:03 +02:00
2019-10-28 12:25:06 +01:00
const populateFetch = require ( './populate' ) ;
2019-06-03 21:00:03 +02:00
const PIVOT _PREFIX = '_pivot_' ;
const getDatabaseName = connection => {
const dbName = _ . get ( connection . settings , 'database' ) ;
const dbSchema = _ . get ( connection . settings , 'schema' , 'public' ) ;
switch ( _ . get ( connection . settings , 'client' ) ) {
case 'sqlite3' :
return 'main' ;
case 'pg' :
return ` ${ dbName } . ${ dbSchema } ` ;
case 'mysql' :
return dbName ;
default :
return dbName ;
}
} ;
2020-01-17 10:42:32 +01:00
module . exports = ( { models , target } , ctx ) => {
2019-06-03 21:00:03 +02:00
const { GLOBALS , connection , ORM } = ctx ;
// Parse every authenticated model.
const updates = Object . keys ( models ) . map ( async model => {
const definition = models [ model ] ;
definition . globalName = _ . upperFirst ( _ . camelCase ( definition . globalId ) ) ;
definition . associations = [ ] ;
// Define local GLOBALS to expose every models in this file.
GLOBALS [ definition . globalId ] = { } ;
2019-07-11 10:14:50 +02:00
// Add some information about ORM & client connection & tableName
2019-06-03 21:00:03 +02:00
definition . orm = 'bookshelf' ;
definition . databaseName = getDatabaseName ( connection ) ;
definition . client = _ . get ( connection . settings , 'client' ) ;
2020-04-28 15:44:05 +02:00
definition . primaryKey = 'id' ;
definition . primaryKeyType = 'integer' ;
2019-06-03 21:00:03 +02:00
// Use default timestamp column names if value is `true`
if ( _ . get ( definition , 'options.timestamps' , false ) === true ) {
_ . set ( definition , 'options.timestamps' , [ 'created_at' , 'updated_at' ] ) ;
}
// Use false for values other than `Boolean` or `Array`
if (
! _ . isArray ( _ . get ( definition , 'options.timestamps' ) ) &&
! _ . isBoolean ( _ . get ( definition , 'options.timestamps' ) )
) {
_ . set ( definition , 'options.timestamps' , false ) ;
}
// Register the final model for Bookshelf.
const loadedModel = _ . assign (
{
2019-09-20 12:44:24 +02:00
requireFetch : false ,
2019-06-03 21:00:03 +02:00
tableName : definition . collectionName ,
hasTimestamps : _ . get ( definition , 'options.timestamps' , false ) ,
associations : [ ] ,
defaults : Object . keys ( definition . attributes ) . reduce ( ( acc , current ) => {
2020-03-12 16:05:39 +01:00
if ( definition . attributes [ current ] . type && definition . attributes [ current ] . default ) {
2019-06-03 21:00:03 +02:00
acc [ current ] = definition . attributes [ current ] . default ;
}
return acc ;
} , { } ) ,
} ,
definition . options
) ;
2019-10-24 14:07:41 +02:00
const componentAttributes = Object . keys ( definition . attributes ) . filter ( key =>
[ 'component' , 'dynamiczone' ] . includes ( definition . attributes [ key ] . type )
2019-07-01 16:59:14 +02:00
) ;
2019-06-03 21:00:03 +02:00
if ( _ . isString ( _ . get ( connection , 'options.pivot_prefix' ) ) ) {
loadedModel . toJSON = function ( options = { } ) {
const { shallow = false , omitPivot = false } = options ;
const attributes = this . serialize ( options ) ;
if ( ! shallow ) {
const pivot = this . pivot && ! omitPivot && this . pivot . attributes ;
// Remove pivot attributes with prefix.
2020-03-12 16:05:39 +01:00
_ . keys ( pivot ) . forEach ( key => delete attributes [ ` ${ PIVOT _PREFIX } ${ key } ` ] ) ;
2019-06-03 21:00:03 +02:00
// Add pivot attributes without prefix.
const pivotAttributes = _ . mapKeys (
pivot ,
( value , key ) => ` ${ connection . options . pivot _prefix } ${ key } `
) ;
return Object . assign ( { } , attributes , pivotAttributes ) ;
}
return attributes ;
} ;
}
2019-10-22 18:01:03 +02:00
await createComponentModels ( {
model : loadedModel ,
definition ,
ORM ,
GLOBALS ,
} ) ;
2019-07-16 18:05:24 +02:00
2020-07-01 13:03:30 +02:00
if ( ! definition . uid . startsWith ( 'strapi::' ) && definition . modelType !== 'component' ) {
2020-06-29 11:12:53 +02:00
definition . attributes [ 'created_by' ] = {
model : 'user' ,
plugin : 'admin' ,
} ;
definition . attributes [ 'updated_by' ] = {
model : 'user' ,
plugin : 'admin' ,
} ;
}
2019-06-03 21:00:03 +02:00
// Add every relationships to the loaded model for Bookshelf.
// Basic attributes don't need this-- only relations.
2019-07-04 15:27:27 +02:00
Object . keys ( definition . attributes ) . forEach ( name => {
const details = definition . attributes [ name ] ;
2019-06-03 21:00:03 +02:00
if ( details . type !== undefined ) {
return ;
}
2019-07-05 17:17:39 +02:00
const { nature , verbose } =
2020-03-19 16:46:27 +01:00
utilsModels . getNature ( {
attribute : details ,
attributeName : name ,
modelName : model . toLowerCase ( ) ,
} ) || { } ;
2019-06-03 21:00:03 +02:00
// Build associations key
2020-03-12 16:05:39 +01:00
utilsModels . defineAssociations ( model . toLowerCase ( ) , definition , details , name ) ;
2019-06-03 21:00:03 +02:00
let globalId ;
const globalName = details . model || details . collection || '' ;
// Exclude polymorphic association.
if ( globalName !== '*' ) {
2020-05-12 17:20:10 +02:00
globalId = strapi . db . getModel ( globalName . toLowerCase ( ) , details . plugin ) . globalId ;
2019-06-03 21:00:03 +02:00
}
switch ( verbose ) {
case 'hasOne' : {
const target = details . plugin
? strapi . plugins [ details . plugin ] . models [ details . model ]
: strapi . models [ details . model ] ;
const FK = _ . findKey ( target . attributes , details => {
if (
2019-09-09 15:32:02 +02:00
_ . has ( details , 'model' ) &&
2019-06-03 21:00:03 +02:00
details . model === model &&
2019-09-09 15:32:02 +02:00
_ . has ( details , 'via' ) &&
2019-06-03 21:00:03 +02:00
details . via === name
) {
return details ;
}
} ) ;
const columnName = _ . get ( target . attributes , [ FK , 'columnName' ] , FK ) ;
loadedModel [ name ] = function ( ) {
return this . hasOne ( GLOBALS [ globalId ] , columnName ) ;
} ;
break ;
}
case 'hasMany' : {
const columnName = details . plugin
? _ . get (
strapi . plugins ,
2019-11-21 20:34:05 +01:00
[
details . plugin ,
'models' ,
details . collection ,
'attributes' ,
details . via ,
'columnName' ,
] ,
2019-06-03 21:00:03 +02:00
details . via
)
: _ . get (
2019-11-21 20:34:05 +01:00
strapi . models ,
[ model . collection , 'attributes' , details . via , 'columnName' ] ,
2019-06-03 21:00:03 +02:00
details . via
) ;
// Set this info to be able to see if this field is a real database's field.
details . isVirtual = true ;
loadedModel [ name ] = function ( ) {
return this . hasMany ( GLOBALS [ globalId ] , columnName ) ;
} ;
break ;
}
case 'belongsTo' : {
loadedModel [ name ] = function ( ) {
2020-03-12 16:05:39 +01:00
return this . belongsTo ( GLOBALS [ globalId ] , _ . get ( details , 'columnName' , name ) ) ;
2019-06-03 21:00:03 +02:00
} ;
break ;
}
case 'belongsToMany' : {
2020-05-12 16:38:06 +02:00
const targetModel = strapi . db . getModel ( details . collection , details . plugin ) ;
2019-06-03 21:00:03 +02:00
2019-07-05 17:17:39 +02:00
// Force singular foreign key
details . attribute = singular ( details . collection ) ;
details . column = targetModel . primaryKey ;
2019-08-19 11:44:53 +02:00
// Set this info to be able to see if this field is a real database's field.
details . isVirtual = true ;
2019-07-05 17:17:39 +02:00
if ( nature === 'manyWay' ) {
2020-03-27 15:51:23 +01:00
const joinTableName =
details . collectionName || ` ${ definition . collectionName } __ ${ _ . snakeCase ( name ) } ` ;
2019-07-05 17:17:39 +02:00
2020-03-12 16:05:39 +01:00
const foreignKey = ` ${ singular ( definition . collectionName ) } _ ${ definition . primaryKey } ` ;
2019-07-05 17:17:39 +02:00
2020-01-23 23:34:28 +01:00
let otherKey = ` ${ details . attribute } _ ${ details . column } ` ;
if ( otherKey === foreignKey ) {
otherKey = ` related_ ${ otherKey } ` ;
2020-03-20 16:44:25 +01:00
details . attribute = ` related_ ${ details . attribute } ` ;
2020-01-23 23:34:28 +01:00
}
2019-07-05 17:17:39 +02:00
2019-08-19 11:44:53 +02:00
loadedModel [ name ] = function ( ) {
const targetBookshelfModel = GLOBALS [ globalId ] ;
let collection = this . belongsToMany (
targetBookshelfModel ,
joinTableName ,
foreignKey ,
otherKey
) ;
if ( Array . isArray ( details . withPivot ) ) {
return collection . withPivot ( details . withPivot ) ;
}
return collection ;
} ;
2019-07-05 17:17:39 +02:00
} else {
2020-03-27 15:51:23 +01:00
const joinTableName = utilsModels . getCollectionName (
targetModel . attributes [ details . via ] ,
details
) ;
2019-06-03 21:00:03 +02:00
2019-07-05 17:17:39 +02:00
const relationship = targetModel . attributes [ details . via ] ;
2019-06-03 21:00:03 +02:00
2019-07-05 17:17:39 +02:00
// Define PK column
relationship . attribute = singular ( relationship . collection ) ;
relationship . column = definition . primaryKey ;
2019-06-03 21:00:03 +02:00
2019-07-05 17:17:39 +02:00
// Sometimes the many-to-many relationships
// is on the same keys on the same models (ex: `friends` key in model `User`)
if (
` ${ details . attribute } _ ${ details . column } ` ===
` ${ relationship . attribute } _ ${ relationship . column } `
) {
relationship . attribute = singular ( details . via ) ;
}
2019-06-03 21:00:03 +02:00
2019-08-19 11:44:53 +02:00
loadedModel [ name ] = function ( ) {
const targetBookshelfModel = GLOBALS [ globalId ] ;
2019-07-05 17:17:39 +02:00
2019-08-19 11:44:53 +02:00
const foreignKey = ` ${ relationship . attribute } _ ${ relationship . column } ` ;
const otherKey = ` ${ details . attribute } _ ${ details . column } ` ;
2019-06-03 21:00:03 +02:00
2019-08-19 11:44:53 +02:00
let collection = this . belongsToMany (
targetBookshelfModel ,
joinTableName ,
foreignKey ,
otherKey
) ;
2019-06-03 21:00:03 +02:00
2019-08-19 11:44:53 +02:00
if ( Array . isArray ( details . withPivot ) ) {
return collection . withPivot ( details . withPivot ) ;
}
2019-07-05 17:17:39 +02:00
2019-08-19 11:44:53 +02:00
return collection ;
} ;
}
2019-06-03 21:00:03 +02:00
break ;
}
case 'morphOne' : {
const model = details . plugin
? strapi . plugins [ details . plugin ] . models [ details . model ]
: strapi . models [ details . model ] ;
const globalId = ` ${ model . collectionName } _morph ` ;
2020-03-16 23:50:15 +01:00
const filter = _ . get ( model , [ 'attributes' , details . via , 'filter' ] , 'field' ) ;
2019-06-03 21:00:03 +02:00
loadedModel [ name ] = function ( ) {
return this . morphOne (
GLOBALS [ globalId ] ,
details . via ,
` ${ definition . collectionName } `
) . query ( qb => {
2020-03-16 23:50:15 +01:00
qb . where ( filter , name ) ;
2019-06-03 21:00:03 +02:00
} ) ;
} ;
break ;
}
case 'morphMany' : {
const collection = details . plugin
? strapi . plugins [ details . plugin ] . models [ details . collection ]
: strapi . models [ details . collection ] ;
const globalId = ` ${ collection . collectionName } _morph ` ;
2020-03-16 23:50:15 +01:00
const filter = _ . get ( model , [ 'attributes' , details . via , 'filter' ] , 'field' ) ;
2019-06-03 21:00:03 +02:00
loadedModel [ name ] = function ( ) {
return this . morphMany (
GLOBALS [ globalId ] ,
details . via ,
` ${ definition . collectionName } `
) . query ( qb => {
2020-03-16 23:50:15 +01:00
qb . where ( filter , name ) . orderBy ( 'order' ) ;
2019-06-03 21:00:03 +02:00
} ) ;
} ;
break ;
}
case 'belongsToMorph' :
case 'belongsToManyMorph' : {
const association = definition . associations . find (
association => association . alias === name
) ;
const morphValues = association . related . map ( id => {
2020-03-12 16:05:39 +01:00
let models = Object . values ( strapi . models ) . filter ( model => model . globalId === id ) ;
2019-06-03 21:00:03 +02:00
2019-07-18 10:55:13 +02:00
if ( models . length === 0 ) {
2020-03-12 16:05:39 +01:00
models = Object . values ( strapi . components ) . filter ( model => model . globalId === id ) ;
2019-07-18 10:55:13 +02:00
}
2019-06-03 21:00:03 +02:00
if ( models . length === 0 ) {
models = Object . keys ( strapi . plugins ) . reduce ( ( acc , current ) => {
2020-03-12 16:05:39 +01:00
const models = Object . values ( strapi . plugins [ current ] . models ) . filter (
model => model . globalId === id
) ;
2019-06-03 21:00:03 +02:00
if ( acc . length === 0 && models . length > 0 ) {
acc = models ;
}
return acc ;
} , [ ] ) ;
}
if ( models . length === 0 ) {
strapi . log . error ( ` Impossible to register the ' ${ model } ' model. ` ) ;
2020-03-12 16:05:39 +01:00
strapi . log . error ( 'The collection name cannot be found for the morphTo method.' ) ;
2019-06-03 21:00:03 +02:00
strapi . stop ( ) ;
}
return models [ 0 ] . collectionName ;
} ) ;
// Define new model.
const options = {
2019-10-25 10:12:35 +02:00
requireFetch : false ,
2019-06-03 21:00:03 +02:00
tableName : ` ${ definition . collectionName } _morph ` ,
[ definition . collectionName ] : function ( ) {
return this . belongsTo (
GLOBALS [ definition . globalId ] ,
` ${ definition . collectionName } _id `
) ;
} ,
related : function ( ) {
return this . morphTo (
name ,
2020-03-12 16:05:39 +01:00
... association . related . map ( ( id , index ) => [ GLOBALS [ id ] , morphValues [ index ] ] )
2019-06-03 21:00:03 +02:00
) ;
} ,
} ;
GLOBALS [ options . tableName ] = ORM . Model . extend ( options ) ;
// Set polymorphic table name to the main model.
target [ model ] . morph = GLOBALS [ options . tableName ] ;
// Hack Bookshelf to create a many-to-many polymorphic association.
// Upload has many Upload_morph that morph to different model.
loadedModel [ name ] = function ( ) {
if ( verbose === 'belongsToMorph' ) {
2020-03-12 16:05:39 +01:00
return this . hasOne ( GLOBALS [ options . tableName ] , ` ${ definition . collectionName } _id ` ) ;
2019-06-03 21:00:03 +02:00
}
2020-03-12 16:05:39 +01:00
return this . hasMany ( GLOBALS [ options . tableName ] , ` ${ definition . collectionName } _id ` ) ;
2019-06-03 21:00:03 +02:00
} ;
break ;
}
default : {
break ;
}
}
} ) ;
// Call this callback function after we are done parsing
// all attributes for relationships-- see below.
2019-12-03 11:27:15 +01:00
const parseValue = createParser ( ) ;
2019-06-03 21:00:03 +02:00
try {
// External function to map key that has been updated with `columnName`
const mapper = ( params = { } ) => {
2019-08-08 12:03:57 +02:00
Object . keys ( params ) . map ( key => {
const attr = definition . attributes [ key ] || { } ;
2019-12-05 11:37:07 +01:00
params [ key ] = parseValue ( attr . type , params [ key ] ) ;
2019-08-08 12:03:57 +02:00
} ) ;
2019-06-03 21:00:03 +02:00
return _ . mapKeys ( params , ( value , key ) => {
const attr = definition . attributes [ key ] || { } ;
2020-03-12 16:05:39 +01:00
return _ . isPlainObject ( attr ) && _ . isString ( attr [ 'columnName' ] ) ? attr [ 'columnName' ] : key ;
2019-06-03 21:00:03 +02:00
} ) ;
} ;
2019-07-29 18:00:01 +02:00
// Extract association except polymorphic.
const associations = definition . associations . filter (
association => association . nature . toLowerCase ( ) . indexOf ( 'morph' ) === - 1
) ;
// Extract polymorphic association.
const polymorphicAssociations = definition . associations . filter (
association => association . nature . toLowerCase ( ) . indexOf ( 'morph' ) !== - 1
) ;
2019-06-03 21:00:03 +02:00
// Update serialize to reformat data for polymorphic associations.
loadedModel . serialize = function ( options ) {
const attrs = _ . clone ( this . attributes ) ;
if ( options && options . shallow ) {
return attrs ;
}
const relations = this . relations ;
2019-10-22 18:01:03 +02:00
componentAttributes . forEach ( key => {
2019-10-24 14:07:41 +02:00
if ( ! _ . has ( relations , key ) ) return ;
2019-06-16 19:45:42 +02:00
2019-10-24 14:07:41 +02:00
const attr = definition . attributes [ key ] ;
const { type } = attr ;
switch ( type ) {
case 'component' : {
const { repeatable } = attr ;
2020-03-12 16:05:39 +01:00
const components = relations [ key ] . toJSON ( ) . map ( el => el . component ) ;
2019-10-24 14:07:41 +02:00
2020-03-12 16:05:39 +01:00
attrs [ key ] = repeatable === true ? components : _ . first ( components ) || null ;
2019-10-24 14:07:41 +02:00
break ;
}
case 'dynamiczone' : {
attrs [ key ] = relations [ key ] . toJSON ( ) . map ( el => {
const componentKey = Object . keys ( strapi . components ) . find (
2020-03-12 16:05:39 +01:00
key => strapi . components [ key ] . collectionName === el . component _type
2019-10-24 14:07:41 +02:00
) ;
return {
_ _component : strapi . components [ componentKey ] . uid ,
... el . component ,
} ;
} ) ;
break ;
}
default : {
throw new Error ( ` Invalid type for attribute ${ key } : ${ type } ` ) ;
}
2019-06-16 19:45:42 +02:00
}
} ) ;
2019-06-03 21:00:03 +02:00
polymorphicAssociations . map ( association => {
// Retrieve relation Bookshelf object.
const relation = relations [ association . alias ] ;
if ( relation ) {
// Extract raw JSON data.
2020-03-12 16:05:39 +01:00
attrs [ association . alias ] = relation . toJSON ? relation . toJSON ( options ) : relation ;
2019-06-03 21:00:03 +02:00
// Retrieve opposite model.
2020-05-15 14:45:25 +02:00
const model = strapi . db . getModel (
2019-12-10 16:21:21 +01:00
association . collection || association . model ,
association . plugin
) ;
2019-06-03 21:00:03 +02:00
// Reformat data by bypassing the many-to-many relationship.
switch ( association . nature ) {
case 'oneToManyMorph' :
2020-03-12 16:05:39 +01:00
attrs [ association . alias ] = attrs [ association . alias ] [ model . collectionName ] || null ;
2019-06-03 21:00:03 +02:00
break ;
case 'manyToManyMorph' :
attrs [ association . alias ] = attrs [ association . alias ] . map (
rel => rel [ model . collectionName ]
) ;
break ;
2019-12-10 16:21:21 +01:00
case 'oneMorphToOne' : {
const obj = attrs [ association . alias ] ;
if ( obj === undefined || obj === null ) {
break ;
}
const contentType = strapi . db . getModelByCollectionName (
obj [ ` ${ association . alias } _type ` ]
) ;
attrs [ association . alias ] = {
_ _contentType : contentType ? contentType . globalId : null ,
... obj . related ,
} ;
2019-06-03 21:00:03 +02:00
break ;
2019-12-10 16:21:21 +01:00
}
2019-06-03 21:00:03 +02:00
case 'manyMorphToOne' :
case 'manyMorphToMany' :
2019-12-10 16:21:21 +01:00
attrs [ association . alias ] = attrs [ association . alias ] . map ( obj => {
const contentType = strapi . db . getModelByCollectionName (
obj [ ` ${ association . alias } _type ` ]
) ;
return {
_ _contentType : contentType ? contentType . globalId : null ,
... obj . related ,
} ;
} ) ;
2019-06-03 21:00:03 +02:00
break ;
default :
}
}
} ) ;
associations . map ( association => {
const relation = relations [ association . alias ] ;
if ( relation ) {
// Extract raw JSON data.
2020-03-12 16:05:39 +01:00
attrs [ association . alias ] = relation . toJSON ? relation . toJSON ( options ) : relation ;
2019-06-03 21:00:03 +02:00
}
} ) ;
return attrs ;
} ;
2019-07-30 11:22:44 +02:00
// Initialize lifecycle callbacks.
loadedModel . initialize = function ( ) {
2019-08-07 02:34:03 -07:00
// Load bookshelf plugin arguments from model options
this . constructor . _ _super _ _ . initialize . apply ( this , arguments ) ;
2019-06-03 21:00:03 +02:00
this . on ( 'fetching fetching:collection' , ( instance , attrs , options ) => {
2019-10-28 12:25:06 +01:00
populateFetch ( definition , options ) ;
2019-06-03 21:00:03 +02:00
} ) ;
2019-12-05 11:37:07 +01:00
this . on ( 'saving' , ( instance , attrs ) => {
2019-12-05 12:29:24 +01:00
instance . attributes = _ . assign ( instance . attributes , mapper ( attrs ) ) ;
2019-06-03 21:00:03 +02:00
} ) ;
2019-12-05 11:37:07 +01:00
const formatValue = createFormatter ( definition . client ) ;
function formatEntry ( entry ) {
Object . keys ( entry . attributes ) . forEach ( key => {
const attr = definition . attributes [ key ] || { } ;
entry . attributes [ key ] = formatValue ( attr , entry . attributes [ key ] ) ;
} ) ;
}
2019-06-03 21:00:03 +02:00
2020-04-24 10:55:09 +02:00
this . on ( 'saved fetched fetched:collection' , instance => {
2019-12-05 11:37:07 +01:00
if ( Array . isArray ( instance . models ) ) {
2019-12-05 12:29:24 +01:00
instance . models . forEach ( entry => formatEntry ( entry ) ) ;
2019-12-05 11:37:07 +01:00
} else {
formatEntry ( instance ) ;
}
} ) ;
2019-06-03 21:00:03 +02:00
} ;
loadedModel . hidden = _ . keys (
_ . keyBy (
_ . filter ( definition . attributes , ( value , key ) => {
if (
2019-09-09 15:32:02 +02:00
_ . has ( value , 'columnName' ) &&
2019-06-03 21:00:03 +02:00
! _ . isEmpty ( value . columnName ) &&
value . columnName !== key
) {
return true ;
}
} ) ,
'columnName'
)
) ;
GLOBALS [ definition . globalId ] = ORM . Model . extend ( loadedModel ) ;
// Expose ORM functions through the `strapi.models[xxx]`
// or `strapi.plugins[xxx].models[yyy]` object.
target [ model ] = _ . assign ( GLOBALS [ definition . globalId ] , target [ model ] ) ;
// Push attributes to be aware of model schema.
target [ model ] . _attributes = definition . attributes ;
target [ model ] . updateRelations = relations . update ;
2020-03-19 16:46:27 +01:00
target [ model ] . deleteRelations = relations . deleteRelations ;
2019-06-03 21:00:03 +02:00
2019-07-16 15:31:15 +02:00
await buildDatabaseSchema ( {
2019-06-03 21:00:03 +02:00
ORM ,
definition ,
loadedModel ,
connection ,
model : target [ model ] ,
} ) ;
2019-07-16 15:31:15 +02:00
2019-10-22 18:01:03 +02:00
await createComponentJoinTables ( { definition , ORM } ) ;
2019-06-03 21:00:03 +02:00
} catch ( err ) {
2020-03-12 16:05:39 +01:00
if ( err instanceof TypeError || err instanceof ReferenceError ) {
strapi . stopWithError ( err , ` Impossible to register the ' ${ model } ' model. ` ) ;
}
2020-03-27 15:51:23 +01:00
if ( [ 'ER_TOO_LONG_IDENT' ] . includes ( err . code ) ) {
strapi . stopWithError (
err ,
2020-03-30 14:39:31 +02:00
` A table name is too long. If it is the name of a join table automatically generated by Strapi, you can customise it by adding \` collectionName: "customName" \` in the corresponding model's attribute.
When this happens on a manyToMany relation , make sure to set this parameter on the dominant side of the relation ( e . g : where \ ` dominant: true \` is set) `
2020-03-27 15:51:23 +01:00
) ;
}
2020-03-12 16:05:39 +01:00
strapi . stopWithError ( err ) ;
2019-06-03 21:00:03 +02:00
}
} ) ;
return Promise . all ( updates ) ;
} ;