Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Break sequelize models in separate folders

My real question is: Is it possible to work with sequelize having the Models in separate folders?

I'm asking this because i'm trying to work with a modular structure in my application, to accomplish that i need to have the model, the controller and the routes in the same folder, here's what i mean:

├── node_modules
├── src
│   ├── client
│   │   └── ... //Frontend things managed by angular (like views, etc...)
│   └── server
|       ├── components
|       |   ├── db
|       |   |   ├── migrations
|       |   |   |   ├── users.js
|       |   |   |   └── ...
|       |   |   ├── seeders
|       |   |   ├── config.json
|       |   |   ├── options.json
|       |   |   └── index.js 
|       |   ├── env
|       |   └── ...
│       ├── modules //By module i mean an entity
|       |   ├── users
|       |   |   ├── users.model.js
|       |   |   ├── users.controller.js
|       |   |   └── index.js //Here i define the routes
|       |   └── ...
|       └── ...
|
├── package.json
└── server.js

How could i do that? how could i split the models into separate folders?

Maybe what i'm asking for is: How could i configure the models/index.js script to read the models from each directory?

models/index.js

'use strict';

var fs        = require('fs');
var path      = require('path');
var Sequelize = require('sequelize');
var basename  = path.basename(module.filename);
var env       = process.env.NODE_ENV || 'development';
var config    = require(__dirname + '/../config.json')[env];
var db        = {};

if (config.use_env_variable) {
  var sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
  var sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(function(file) {
    return (file.indexOf('.') !== 0) && (file !== basename);
  })
  .forEach(function(file) {
    if (file.slice(-3) !== '.js') return;
    var model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach(function(modelName) {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

Something i was thinking is to look for the xxx.model.js under each folder of the modules directory having a structure like this:

modules
├── index.js //The above script configured to read the x.model.js in each folder
├── users
|   ├── users.model.js
|   ├── users.controller.js
|   └── ...
├── questions
|   ├── questions.model.js
|   ├── questions.controller.js
|   └── ...
└── ...

NOTE: I come from a Laravel background, i'm guessing how are migrations and models different in sequelize since when you define a model you tell the type, etc.. of the column, the same as the migration...

like image 637
Jonathan Solorzano Avatar asked Sep 13 '15 03:09

Jonathan Solorzano


2 Answers

You have to read all the models from different folders exist in your given directory.

Let's add sortDir function into models/index.js

sortDir will sort all the js files exist in each folder we have in our directory into an array called files. After calling the function we can easily read our models from files array.

const files = [];
const sortDir = (maniDir) => {
  const folders = [];
  const CheckFile = filePath => (fs.statSync(filePath).isFile());
  const sortPath = (dir) => {
    fs
      .readdirSync(dir)
      .filter(file => (file.indexOf(".") !== 0) && (file !== "index.js"))
      .forEach((res) => {
        const filePath = path.join(dir, res);
        if (CheckFile(filePath)) {
          files.push(filePath);
        } else {
          folders.push(filePath);
        }
      });
  };
  folders.push(maniDir);
  let i = 0;
  do {
    sortPath(folders[i]);
    i += 1;
  } while (i < folders.length);
};
sortDir(__dirname);

Now, you can read each model after sorting them from array files.

files
  .forEach((file) => {
    const model = require(file)(sequelize, Sequelize.DataTypes);
    db[model.name] = model;
  });

Hope it helps!

like image 52
Jalal Avatar answered Oct 03 '22 01:10

Jalal


I hope, this will save your time.

import fs from "fs";
import path from "path";
import Sequelize from "sequelize";
import { getConfig } from "../../lib/config";
const db = {};
// Load config file based on the enviroment
const config = getConfig();

let sequelize = null;
const { Op } = Sequelize;
const operatorsAliases = {
  $gt: Op.gt,
  $gte: Op.gte,
  $ne: Op.ne,
  $in: Op.in,
  $or: Op.or,
  $and: Op.and,
  $like: Op.like,
};

if (config.useEnvVariable) {
  sequelize = new Sequelize(process.env[config.useEnvVariable], config);
} else {
  const databaseConf = config[process.env.NODE_ENV];
  sequelize = new Sequelize(
    databaseConf.database,
    databaseConf.username,
    databaseConf.password,
    {
      host: databaseConf.host,
      dialect: databaseConf.dialect,
      operatorsAliases,
    },
  );
}

const files = [];
const sortDir = maniDir => {
  const folders = [];
  const CheckFile = filePath => fs.statSync(filePath).isFile();
  const sortPath = dir => {
    fs
      .readdirSync(dir)
      .filter(file => file.indexOf(".") !== 0 && file !== "index.js")
      .forEach(res => {
        const filePath = path.join(dir, res);
        if (filePath.indexOf("Schema") === -1) {
          if (CheckFile(filePath)) {
            files.push(filePath);
          } else {
            folders.push(filePath);
          }
        }
      });
  };
  folders.push(maniDir);
  let i = 0;
  do {
    sortPath(folders[i]);
    i += 1;
  } while (i < folders.length);
};
sortDir(__dirname);

files.forEach(file => {
  const model = sequelize.import(file);
  db[model.name] = model;
});

Object.keys(db).forEach(modelName => {
  console.log(modelName);
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.sequelize.sync({
   logging: false,
 });

export default db;
like image 23
Afsal KK Avatar answered Oct 03 '22 01:10

Afsal KK