Include Sequelize Associated Models data via params di Feathersjs dan 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": "[email protected]",
"userProfileId": 1
}]
userProfilesId
merupakan foreign_key ke model user_profiles
dengan model asosiasi one to one relationship.
Hasil yang diinginkan
data: [{
"id": 1,
"email": "[email protected]",
"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
- Getters/Setters custom akan diabaikan
- Associated Data akan ditampilkan dengan sedikit berbeda
- Validasi pada tingkatan model akan diabaikan Dengan kelebihan kecepatan proses yang dapat diperoleh dengan menggunakan opsi ini. Namun demikian hal sebagai berikut akan diabaikan;
# 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;
};
};