Связи между таблицами sequelize в FeathersJS

Данная статья будет про то как можно строить связи между таблицами FeathersJS при использование ORM sequelize. Я бы очень хотел чтоб такой материал был уже на русском (или даже на английском) но к сожалению не нашёл.

Шаг 1 – знакомство с ORM sequelize

Итак, чтобы использовать ORM sequelize нужно понять её принцип работы и то как она позволяет делать связи между моделями. Рекомендую читать несколько раз (и внимательно) вот эту статью: http://docs.sequelizejs.com/manual/tutorial/associations.html, тут описано подробно про каждый возможный тип связи.

Шаг 2 – Понять как работает Feathers JS с sequelize

Сразу приведу пример модели в который описывается связь:

const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const category = sequelizeClient.define('category', {
    icon: {
      type: DataTypes.STRING,
      allowNull: true
    },
    parent: {
      type: DataTypes.INTEGER.UNSIGNED,
      allowNull: false
    }
  }, {
    timestamps: false, убираем поля createdAt и updatedAt
    freezeTableName: true,
    underscored: true, // мне удобнее так
    hooks: {
      beforeCount(options) {
        options.raw = false;
      }
    }
  });
  // Дальше описываем связь
  category.associate = function (models) {
    models.category.hasMany(models.category_translate, {
      constraints: true,
      foreignKey: 'category_id', // это поле с таблицы category_translate
      as: 'translate' // это алиас таблицы который желаю использовать 
  };
  return category;
};

Теперь создадим новое hook которое назовём translate и там соединяем нашу модель category_translate.

module.exports = function (options = {}) {
  return function categoryTranslate (hook) {
    const AssociatedModel = hook.app.services['category-translate'].Model; // выбираем модель которую хотели связать
    
    hook.params.sequelize = {
       include: [{
        model: AssociatedModel,
        as: 'translate', // тут нужно писать тот же алиас который использовали в модели category.models
        query: {
          $limit: 1,
          $select: [
              'country_icon'
          ]
        },
        where: { // если хотим задать какие-то параметры для таблицы category_translate то их нужно писать тут
            lang: hook.params.query['$language'] // это для примера
        }
        }]
    };
    delete hook.params.query['$language'];
    delete hook.params.query.include;

    return Promise.resolve(hook);
  };
};

Результаты

Теперь если сделать вот такой запрос:

то в результате получим нужный результат:

Присоединяйтесь к сообществу Feathers в Телеграмме: t.me/featherjs

Всем спасибо за внимание.

Valeriu :