-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make instances instanceof Model, with ES6 classes #5924
Make instances instanceof Model, with ES6 classes #5924
Conversation
a4e1f09
to
d68fbc2
Compare
Apparently native modules do not compile, any help? |
Try adding the addons:
apt:
sources:
- llvm-toolchain-precise-3.6
- ubuntu-toolchain-r-test
packages:
- clang-3.6
- g++-4.8 |
@sushantdhiman didnt work :/ |
diff too large :( |
Can you rebase this? Might help with the tests |
Then we promise to review it quickly! :) |
I will try, hopefully there were no changes in model.js or instance.js... It's a pain to rebase this because for git it's just one huge delete and one huge insert. |
@felixfbecker is there a document describing your design and thoughts behind this anywhere? Syntax examples etc. |
@mickhansen I outlined my thoughts in the initial PR #5877, there are also some comments linked |
@felixfbecker Thanks i've looked through a bit of it. |
d402481
to
cbbe6db
Compare
I think I cought everything. Had to essentially reimplement every single commit on master since my PR. @mickhansen everything that was on the prototype of |
@felixfbecker We'd need a way to overwrite name, cause i use lowercase model names but i'd like pascal case class names. We don't need to main |
this.Instance.prototype.$Model = | ||
this.Instance.prototype.Model = this; | ||
this.prototype.$Model = | ||
this.prototype.Model = this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be removed completely.
I assume you made no changes when merging Instance/Model other than doing a single file and doing all Model methods as static, correct? What is the syntax for defining attributes, model name, table name, underscored etc, with |
Ideally i would love to work on a doc describing how to upgrade from ES5 model to both ES6 and ES7 models (defining needed properties), this doc could be exploratory and we could work from that. |
But we could likely merge this for the sake of no-rebases and then move forward with the design after, as long as we arent cutting releases theres room to maneuver. |
We could pass the model name to class User extends Sequelize.Model {}
Model.init(User.name, {}, {}, sequelize.modelManager) Then again,
Basically yes. Plus I changed
So you would make
That would be nice, so other PRs can target the class implementation. So it is decided that Node 4/6 is required (for classes)? Do you want me to squash or keep it in multiple commits? I would then go ahead and refactor other parts of the library to classes and potentially arrow functions. |
Should be sufficient for now.
That would be the goal, addModel would then return a model aswell, since we need a version of the model that is aware of sequelize.
No, model.init is a mapper for define (imo), i'd look to a better design for ES6 and a design for ES7 we could strive to in the future. The design could be ES7 decorators that would work for ES6 aswell (although without the decorator syntax), or it could be I agree that most of the power will come with static props and decorators, but i think it makes sense to have an intermediate design aswell (since static props and decorators need to map to that in any case). We've pretty much decided on Node 4.0+ atleast, and i don't think we'll go for Node 6.0+ only. I'll squash when i merge. |
I don't know what you mean with class User extends Sequelize.Model {
public username: string;
myMethod() {
return 'hello';
}
}
User.init({username: Sequelize.STRING}, {tableName: 'users'}) // attach metadata, this can alternatively be done with decorators
sequelize.addModel(Model) // adds the model to the modelManager and sets User.modelManager
The idea is that
|
cbbe6db
to
9f107fd
Compare
How can the build fail because of style issues (mixed double/single quotes) if I only copy+pasted code? |
If we're going to be doing ES6 classes they should be decoupled.
I thought all decorators were basically just functions? |
If you want to support that scenario... Imo it should also be supported that I only define my class, set the connection/modelManager whatever that should be used on it and then use this class directly. I do not want to use the return value of some function as my model class... Eg it should be I think having one sequlize connection instance is the most common use case. Cloning the model class seems overkill to me to implement this feature and is tricky to do in JS (a class is just a function). I think if people want to use different connections with one model class, there should be an option to pass it to every function that needs a connection, eg |
If you want I think it would be fine to split this into smaller commits, but if not, squashing is fine by me as well |
I'm hoping to do a final review and merge over the weekend :) |
@@ -632,7 +632,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() { | |||
this.task = task; | |||
return task.createUser({ username: 'foo' }); | |||
}).then(function(createdUser) { | |||
expect(createdUser.Model).to.equal(User); | |||
expect(createdUser.constructor).to.equal(User); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor thing, but couldn't this be instanceof?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.
@felixfbecker I've reviewed the changes to model.js locally, so I'm ready to merge - Do you want to do the squashing dance, or do you want me to mono-squash it? |
@janmeier I cannot think of a good way to squash this into more than one commit, so go ahead :) |
Thanks for the big effort @felixfbecker 🎉 🎉 🎉 |
Yay! Thanks a bunch @felixfbecker |
Is there docs, how to use I have this code: // schema is sequelize instance
let Model = schema.define('news', {
title: {
type: Sequelize.STRING,
defaultValue: null
},
content: {
type: Sequelize.TEXT,
allowNull: true
}
}); How I could specify:
class Model extends Sequelize.Model {
} ? What I need to do? Thanks. |
@nervgh There is no documentation yet because the API is not finished and will probably change a lot. Currently you have to call Model.init(attributes, options, sequelize.modelManager);
sequelize.modelManager.add(Model)
Please note though that |
Yes, I know, I do it. But I want use inheritance for overriding a couple of built-in methods: class Model extends Sequelize.Model {
save(options) {
// my code here
return super.save(options);
}
} @felixfbecker thank you ✌️ I will try your recommendations. |
@nervgh You can do that with |
|
@OLDIN that is completely wrong and has nothing to do with the new syntax. A constructor does not have a return value. This is a very old PR. If you want to discuss anything, please move the discussion to Slack, Gitter or a new issue. |
@felixfbecker offer your working version. I will be glad to use. |
@OLDIN I can point you to the TypeScript definitions, which contain some examples: http://typed-sequelize.surge.sh/ I'm gonna lock this thread now to prevent spamming participants with notifications |
This PR is a reimplementation of #5877 with ES6 classes. Reasoning is performance and that 4.0 will probably require Node >=4 or even 6.