I have two folders under the 'services' folder. They are working calling the service individually. Now I want expand one model to include the related model and this is giving an error 'info: TypeError: Cannot read property 'Model' of undefined'
The database exists, sql server, and the relations are there too.
file services\mic\activity\index.js
'use strict';
const service = require('feathers-sequelize');
const activity = require('./activity-model');
const hooks = require('./hooks/index');
module.exports = function () {
const app = this;
const options = {
Model: activity(app.get('mic_sequelize'))
};
app.use('/mic/activity', service(options));
const activityService = app.service('/mic/activity');
activityService.before(hooks.before);
activityService.after(hooks.after);
};
file services\mic\activity\activity-model.js
'use strict';
const Sequelize = require('sequelize');
module.exports = function (sequelize) {
const activity = sequelize.define('activity', {
activity_pk: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
unique: true
},
activity_plan_pk: {
type: Sequelize.INTEGER,
allowNull: false,
unique: false
},
change_order_pk: {
type: Sequelize.INTEGER,
allowNull: true,
unique: false
},
description: {
type: Sequelize.STRING(255),
allowNull: false,
unique: false
},
id: {
type: Sequelize.STRING(255),
allowNull: false,
unique: true
}
}, {
freezeTableName: true,
paranoid: false,
timestamps : false,
underscored : false,
tableName: 'Activity',
classMethods: {
associate() {
activity.belongsTo(sequelize.models.activity_plan, {
allowNull: true,
as: 'activity_plan'
});
activity.belongsTo(sequelize.models.change_order, {
allowNull: false,
as: 'change_order'
});
}
}
});
return activity;
};
file services\mic\activity\hooks\index.js
'use strict';
const globalHooks = require('../../../../hooks');
const hooks = require('feathers-hooks');
const auth = require('feathers-authentication').hooks;
exports.before = {
all: [],
find: [
getRelatedInfo()
],
get: [
getRelatedInfo()
],
create: [],
update: [],
patch: [],
remove: []
};
exports.after = {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
};
function getRelatedInfo() {
return function (hook) {
hook.params.sequelize = {
attributes: [
'activity_pk',
'activity_plan_pk',
'change_order_pk',
['description', 'activity_description'],
['id', 'activity_id']
],
include: [
{
model: hook.app.services.activity_plan.Model,
as: 'activity_plan',
required: false,
attributes: [
['description', 'activity_plan_description'],
['id', 'activity_plan_id']
]
}
]
}
};
return Promise.resolve(hook);
}
file services\mic\activity_plan\index.js
'use strict';
const service = require('feathers-sequelize');
const activity_plan = require('./activity_plan-model');
const hooks = require('./hooks/index');
module.exports = function () {
const app = this;
const options = {
Model: activity_plan(app.get('mic_sequelize'))
};
app.use('/mic/activity_plan', service(options));
const activityplanService = app.service('/mic/activity_plan');
activityplanService.before(hooks.before);
activityplanService.after(hooks.after);
};
file services\mic\activity_plan\activity_plan-model.js
'use strict';
const Sequelize = require('sequelize');
module.exports = function (sequelize) {
const activity_plan = sequelize.define('activity_plan', {
activity_plan_pk: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
unique: true
},
description: {
type: Sequelize.STRING(255),
allowNull: false,
unique: false
},
id: {
type: Sequelize.STRING(255),
allowNull: false,
unique: true
}
}, {
freezeTableName: true,
paranoid: false,
timestamps : false,
underscored : false,
tableName: 'Activity_Plan',
classMethods: {
associate() {
activity_plan.hasMany(sequelize.models.activity, {
as: 'activity_plan',
foreignKey: 'activity_plan_pk',
targetKey: 'activity_plan_pk'
});
}
}
});
return activity_plan;
};
file service\mic\activity_plan\hooks\index.js
'use strict';
const globalHooks = require('../../../../hooks');
const hooks = require('feathers-hooks');
const auth = require('feathers-authentication').hooks;
exports.before = {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
};
exports.after = {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
};
Question
I think somewhere I have a misconfiguration. I used a working example app of my self where the services doesn't have subfolders and the relation is made the same way. That is working. Any idea where the issue is?
Solving
Okay. So I moved activity and activity_Plan back to the root of services without changing anything except file locations. Same error. THen I changed the paths for the service (removed '/mic') and now I get 'activity_plan' is not associated with 'activity'.
Okay, now I reverted my test and have this line model: hook.app.service('/mic/activity_plan').Model
. Then I thought of something. I have custom primary keys, so I need to do something in the hasMany, belongsTo parts looking into that
So now I made a second database which is made through sequelize (the tables) strangly, exact same problem.
If I look at this line at Model.validateIncludedElement (D:\Workspace\Projects\01. Live Customers\Mexon Technology\Projects - Mexon\MexonInControl\MultiFunctionalPortal\backend\node_modules\sequelize\lib\model.js:558:11)
and then in the code it points to, it may well be an issue with the naming of my models in combination with the line model: hook.app.service('/mfp/sys_metadata').Model
in my code.
Oh dear. I totally forgot to initialize the associations in the index.js file of the service subfolder:
Object.keys(sequelize.models).forEach(function(modelName) {
if ("associate" in sequelize.models[modelName]) {
sequelize.models[modelName].associate();
}
});
sequelize.sync(
{
force: false
}
);