Include association di Sequelize dalam lingkungan feathersjs via params.include.sequelize dan membuat field dengan data type Virtual
Contoh kasus untuk dua model yang memiliki asosiasi dalam sebuah aplikasi feathersjs yang menggunakan Sequelize sebagai Database Driver. Melalui hook yang melakukan modifikasi terhadap params yang berada di dalam context, asosiasi dapat ditampilkan ketika melakukan query terhadap service yang menggunakan models terkait.
Hasil awal misalkan
data: [{
"id": 1,
"email": "user@email.address",
"userProfileId": 1
}]
userProfilesId merupakan foreign_key ke model user_profiles dengan model asosiasi one to one relationship.
Hasil yang diinginkan
data: [{
"id": 1,
"email": "user@email.address",
"userProfileId": 1,
"userProfile": {
"fullName" : "First Last Name", // virtual
"birthDate": "29-03-1992",
"address": "Address"
}
}]
Asosiasi kedua model dapat dilakukan melalui belongsTo() di users model yang akan menambahkan field foreign key userProfileId di dalam model tersebut.
# src/models/users.model.js
// eslint-disable-next-line no-unused-vars
models.associate = function (models) {
// Define associations here
// See http://docs.sequelizejs.com/en/latest/docs/associations/
users.belongsTo(models.userProfiles, {as: 'userProfile'});
};
Generade hooks yang dijalankan pada tahapan before untuk query di service terkait, contoh nama hook adalah populate-users
# src/hooks/populate-users.js
module.exports = function (options = {}) {
return async context => {
const users = context.app.services.users.Model;
context.params.sequelize = {
raw:false,
include: [
{
model: userProfiles,
as: 'userProfile',
attributes: ['fullname','birthdate', 'address']
}
]
};
return context;
};
};
Penambahan context.params.sequelize.include yang berisikan array terhadap model yang terasosiasi dengan model terkait akan melakukan query terpisah terhadap associated model tersebut untuk kemudian menambahkan object dari model yang terasosiasi ke dalam context.result yang ditampilkan ke user.
ref: https://github.com/feathersjs-ecosystem/feathers-sequelize#setting-paramssequelizeinclude
Secara default, operasi yang dilakukan dalam lingkungan feathersjs memiliki option raw:true yang menyebabkan beberapa hal berikut;
via https://github.com/feathersjs-ecosystem/feathers-sequelize#sequelize-raw-queries
# userProfiles model file
fullName: {
type: DataTypes.VIRTUAL
get() {
return this.firstName + ' ' + this.lastName;
}
}
Untuk memungkinkan definisi field dengan data type virtual silahkan tambahkan opsi raw:false di tahapan before atau gunakan hook hydrate
https://github.com/feathersjs-ecosystem/feathers-sequelize#working-with-sequelize-model-instances
Hook terpisah untuk menonaktifkan raw result, misalkan dalam kasus ini ketika kita ingin memanggil model userProfiles secara langsung.
# file ./src/hooks/raw-false.js
module.exports = function (options = {}) {
return async context => {
if (!context.params.sequelize) context.params.sequelize = {};
Object.assign(context.params.sequelize, { raw: false });
return context;
};
};