sequelize / website

Our beloved website that contains all versions of our documentations and the API references.
https://sequelize.org
27 stars 149 forks source link

Best Practice documentation for import (associations) #293

Open chrisgo opened 5 years ago

chrisgo commented 5 years ago

Awesome job getting to v5!

Possibly add a small example "best practice" of how to completely separate the model files in the documentation

http://docs.sequelizejs.com/manual/models-definition.html > Import

is very close but it does not address how to best put the associations into the separate model files

The examples here assume that you have imported all the models into this one file and then code all the associations after all the models have been imported

http://docs.sequelizejs.com/manual/associations.html

I believe most are using this an example prior to v5 https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/

trappar commented 5 years ago

👍 This has me stumped too

chrisgo commented 5 years ago

There is an example here https://github.com/sequelize/express-example/blob/master/models/index.js

brenc commented 5 years ago

Also:

http://docs.sequelizejs.com/manual/models-definition.html > Import

const Project = sequelize.import(__dirname + "/path/to/models/project")

module.exports = (sequelize, DataTypes) => {
  class Project extends sequelize.Model { }
  Project.init({
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  }, { sequelize });
  return Project;
}

This for me crashes with:

TypeError: Class extends value undefined is not a constructor or null

The sequelize instance doesn't appear to have a reference to Model. What works for me is this:

const Project = sequelize.import(__dirname + "/path/to/models/project")

// In the mode file:
const Sequelize = require('sequelize')

module.exports = (sequelize, DataTypes) => {
  class Project extends Sequelize.Model { }
  Project.init({
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  }, { sequelize });
  return Project;
}
jackie1120 commented 5 years ago

Also:

http://docs.sequelizejs.com/manual/models-definition.html > Import

const Project = sequelize.import(__dirname + "/path/to/models/project")

module.exports = (sequelize, DataTypes) => {
  class Project extends sequelize.Model { }
  Project.init({
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  }, { sequelize });
  return Project;
}

This for me crashes with:

TypeError: Class extends value undefined is not a constructor or null

The sequelize instance doesn't appear to have a reference to Model. What works for me is this:

const Project = sequelize.import(__dirname + "/path/to/models/project")

// In the mode file:
const Sequelize = require('sequelize')

module.exports = (sequelize, DataTypes) => {
  class Project extends Sequelize.Model { }
  Project.init({
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  }, { sequelize });
  return Project;
}

This for me crashes also,with: TypeError: Class extends value undefined is not a constructor or null. And i fix it with this method,is this a bug?

const Sequelize = require('sequelize')

module.exports = (sequelize, DataTypes) => {
  class Model extends Sequelize.Model {}
  Model.init({
    email: DataTypes.STRING,
    password: DataTypes.STRING
  }, {
    sequelize,
    modelName: 'user'
  })
  return Model
}
satheeshnatarajan commented 4 years ago
const Sequelize = require('sequelize')

module.exports = (sequelize, DataTypes) => {
  class Model extends Sequelize.Model {}
  Model.init({
    email: DataTypes.STRING,
    password: DataTypes.STRING
  }, {
    sequelize,
    modelName: 'user'
  })
  return Model
}

But associate not working while using import method

papb commented 4 years ago

Thanks for this issue. I was planning to do this for a while already... I really think this would help. I will try to get into this in a few days.

ghost commented 4 years ago

Any update? I have the same issue with TypeError: Class extends value undefined is not a constructor or null. Solution with additional const Sequelize = require('sequelize') in each module file looks for me like dirty hack :disappointed:

papb commented 4 years ago

@irekg I still plan on getting into this, unfortunately I am more busy than expected, hopefully you can wait a bit more :grimacing:

ghost commented 4 years ago

@papb I briefly looked at the code and it it looks like that all we need is another alias in /lib/sequelize.js.

// Aliases
Sequelize.prototype.fn = Sequelize.fn;
Sequelize.prototype.col = Sequelize.col;
Sequelize.prototype.cast = Sequelize.cast;
Sequelize.prototype.literal = Sequelize.literal;
Sequelize.prototype.and = Sequelize.and;
Sequelize.prototype.or = Sequelize.or;
Sequelize.prototype.json = Sequelize.json;
Sequelize.prototype.where = Sequelize.where;
Sequelize.prototype.validate = Sequelize.prototype.authenticate;
Sequelize.prototype.Model = Model; // <-- is it that simple or I'm missing something bigger?

It works fine for me with this alias. I can prepare PR if You like.

papb commented 4 years ago

@irekg Ah, okay, you are thinking of something much smaller than I was. If that single change helps you, I think it is super fine! Feel free to submit a PR.

ghost commented 4 years ago

Also:

http://docs.sequelizejs.com/manual/models-definition.html > Import

const Project = sequelize.import(__dirname + "/path/to/models/project")

module.exports = (sequelize, DataTypes) => {
  class Project extends sequelize.Model { }
  Project.init({
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  }, { sequelize });
  return Project;
}

This for me crashes with:

TypeError: Class extends value undefined is not a constructor or null

The sequelize instance doesn't appear to have a reference to Model. What works for me is this:

const Project = sequelize.import(__dirname + "/path/to/models/project")

// In the mode file:
const Sequelize = require('sequelize')

module.exports = (sequelize, DataTypes) => {
  class Project extends Sequelize.Model { }
  Project.init({
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  }, { sequelize });
  return Project;
}

@brenc Looking at the source code https://github.com/sequelize/sequelize/blob/d041e77e275c3e950cedcdb3a625d891ea8b056b/lib/sequelize.js#L1311

I noticed that it might be possible to do:

module.exports = (sequelize, DataTypes) => {
  class Project extends sequelize.Sequelize.Model { }
  Project.init({
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  }, { sequelize });
  return Project;
}

Haven't tried yet. I will test it tomorrow at work. IMHO If this works then it's the simplest workaround.


Update: tested. It works.

papb commented 4 years ago

@irekg Oh that's right!! So your PR wouldn't be needed after all...

ghost commented 4 years ago

@papb Right. But I think that example in documentation should be updated.

papb commented 4 years ago

Definitely. I will keep this open as a docs issue.