ericmdantas / generator-ng-fullstack

Client, server or fullstack - it's up to you. ng-fullstack gives you the best of the latest.
MIT License
704 stars 102 forks source link

sequelize.js as ORM #26

Open khwerhahn opened 9 years ago

khwerhahn commented 9 years ago

Is there a general interest to support sequelize.js? mongo isn't always going to work for every project.

ericmdantas commented 9 years ago

I have never used it, but it's a good idea.

I'd need help with the dev, though. I don't know its best practices.

khwerhahn commented 9 years ago

Hi @ericmdantas,

I'm glad to help out soon, but I'm currently busy and don't have much time to spare.

In https://github.com/DaftMonk/generator-angular-fullstack/tree/canary they have included it into the project. I'm using the generator for a current project, but have diverted a little bit from how it was implemented there. I keep all models in a model folder which are are loaded in via the index.js in the same folder. There was a reason for this though, since I had to build on top of an existing database and I used sequelize-auto to auto import all the models. But I generally like to have the models all in one folder.

Hope this helps

'use strict';

var fs = require("fs");
var path = require("path");
var config = require('../config/environment');
var Sequelize = require("sequelize");
//var sequelize = new Sequelize(config.dbUrl);
var sequelize = new Sequelize(config.dbUrl.database, config.dbUrl.user, config.dbUrl.password, 
    { 
        host: config.dbUrl.host, 
        dialect: 'postgres', 
        sync: { force: true },
        logging: config.dbUrl.logging,
    });

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

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

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

module.exports = db;

The app.js:

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var express = require('express');
var models = require('./models');
var config = require('./config/environment');

// Setup server
var app = express();
var server = require('http').createServer(app);
var socketio = require('socket.io')(server, {
  serveClient: (config.env === 'production') ? false : true,
  path: '/socket.io-client'
});

require('./config/socketio')(socketio);
require('./config/express')(app);
require('./routes')(app);

var forcedrop = (config.seedDB) ? true : false;

models.sequelize.sync({ force: forcedrop }).success(function () {
  // Populate DB with sample data
  if (config.seedDB) {
     require('./config/seed');
  }

});

exports = module.exports = app;

A typical model would look like this:

address.js

'use strict';

module.exports = function(sequelize, DataTypes) {
  var Address = sequelize.define('address', {

    lat: {
        type: DataTypes.DECIMAL(10,8),
        allowNull: true,
        defaultValue: null,
        validate: { min: -90, max: 90 }
    },
    lng: {
        type: DataTypes.DECIMAL(10,8),
        allowNull: true,
        defaultValue: null,
        validate: { min: -180, max: 180 }
    },
    customer_id: {
      type: DataTypes.INTEGER,
      allowNull: false
    }

  },{
  underscored: true,
   paranoid: true,
    validate: {

        bothCoordsOrNone: function() {
          if ((this.lat === null) === (this.lng === null)) {
            throw new Error('Require either both lat and lng or neither')
          }
        }

    },
    classMethods: {
        associate: function (models) {
          Address.belongsTo(models.customer, { foreignKey:'customer_id'})
        }
    }
  });

  return Address;
}
ericmdantas commented 9 years ago

@khwerhahn, that's very helpful!

I'll take a closer look asap and I'll see where this fits. Thanks!

dmarcelino commented 9 years ago

I'm also tight on time right now due to a deadline closing soon, but one thing I would like to help with would be integrating waterline. Waterline is a multi-adapter ORM with official support for MySQL, PostgreSQL, Mongo, Redis, local memory and disk. Community adapters exist for less mainstream data stores.

Perhaps the biggest disadvantage of waterline compared to sequelize is that it currently doesn't support transactions (balderdashy/waterline#755). Still, there are talks about using knexjs as core component of their SQL adapters (balderdashy/waterline#605) so people could get the best of both worlds.

In the project I'm working now we are using generator-angular-fullstack with waterline instead of mongoose and so far I'm enjoying it :)

ericmdantas commented 9 years ago

@dmarcelino I personally have never used it, but it'd be great to have such integration.

I also have been very busy, but I'd definetely merge a PR on the subject.

itrethan commented 8 years ago

+1 for sequelize.js

justcfx2u commented 8 years ago

SQL is also a requirement for my latest project. Sequelize.js support out-of-the-box would definitely help here.

johnnyPescarul commented 8 years ago

+1 for sequelize

ericmdantas commented 8 years ago

Could anyone use the base of generator as of now and switch from MongoDB/Mongoose to Sequelize? I'd gladly accept the PR and land it on 1.9.

amarewgs commented 8 years ago

+1 for sequelize.js