I am currently studying using NodeJS, Express, PostgreSQL and Sequelize on Scotch.io then I came across this:
'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/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) & (file.slice(-3) === '.js');
})
.forEach(function(file) {
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;
I need someone to please help explain these in plain terms. What exactly is happening here?
I do understand the part where we default to development
is Node environment is not set but I really need clarification of the file reading part i.e where fs
begins.
Thanks a lot.
答案 0 :(得分:7)
Firstly, note that this code is generated by sequelize-cli
by running sequelize init
and is placed in a file called index.js
located in a models/
folder.
1. The Configuration Environment
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);
}
This is helpful for when in production. As an example, I'll show you my code:
module.exports = {
development: {
dialect: 'postgres',
username: '<username name>',
password: 'test',
database: '<db name>',
host: 'localhost'
},
production: {
dialect: 'postgres',
dialectOptions: {
ssl: true
},
protocol: 'postgres',
use_env_variable: 'DATABASE_URL'
}
}
Heroku sets a process variable DATABASE_URL
that I simply point to. The username, password etc are obtained from this, rather than listing them explicitly in config.js
, as development credentials are.
2. Importing/Reading Models
fs
.readdirSync(__dirname)
.filter(function(file) {
return (file.indexOf('.') !== 0) && (file !== basename) & (file.slice(-3) === '.js');
})
.forEach(function(file) {
var model = sequelize['import'](path.join(__dirname, file));
db[model.name] = model;
});
fs.readdirSync
synchronously reads the directory given in its argument. In this case, it's __dirname
, which is the directory that this index.js file is in. Here, the models you defined in models/
directory are pulled in. Notice that the filter function is just making sure that:
Each model file is then keyed into the exports Object with the line db[model.name] = model;
3. Associating Each Model
Object.keys(db).forEach(function(modelName) {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
Lastly, once we have obtained all of the model files (from the previous read), we run each model's associate
function, if it exists. This is a method that's defined in each model file as follows:
module.exports = (sequelize, DataTypes) => {
var Model1 = sequelize.define('Model1',
{ ... })
// Class Method
Model1.associate = function (models) {
Model1.belongsTo(models.Model2)
}
return Model1
}
4. Exported Use
Both an instance of your sequelize database (sequelize
) and an instance of the Sequelize
library are exported.
In this manner we can now do the following:
assume a directory structure of
require('./models').Model1 // access to your models
This is how you'll import and use your models, rather than directly through their definition files. This ensures they're synced and associated properly.
Likewise we have access to sequelize:
require('./models')
.sequelize.sync({ force: true }) // access to your sequelize db
答案 1 :(得分:1)
In plain terms, this is importing all the .js
files from the same directory as this file. This is done through sequelize['import']
method.
Moreover it is assumed that all these files contain sequelize models, as the return value from the import is mapped on dictionary named db
.
db[model.name] = model
Once all the files are imported and models are mapped to db
, a loop is run to call associate
on each model, only if that model contains associate method. Usually associate method is used to define all the associations between the models i.e. hasMany
, hasOne
, belongsTo
etc.