不要怂,就是干,撸起袖子干!

Commit 04e3592e by Simon Schick Committed by GitHub

docs: misc improvements for TS, best practises for classes and changelog fixes (#10850)

1 parent ba5192ce
......@@ -805,14 +805,8 @@ Image.init({
link: Sequelize.STRING
}, { sequelize, modelName: 'image' });
class Comment extends Model {}
Comment.init({
title: Sequelize.STRING,
commentable: Sequelize.STRING,
commentableId: Sequelize.INTEGER
}, { sequelize, modelName: 'comment' });
Comment.prototype.getItem = function(options) {
class Comment extends Model {
getItem(options) {
return this[
'get' +
this.get('commentable')
......@@ -820,7 +814,14 @@ Comment.prototype.getItem = function(options) {
.toUpperCase() +
this.get('commentable').substr(1)
](options);
};
}
}
Comment.init({
title: Sequelize.STRING,
commentable: Sequelize.STRING,
commentableId: Sequelize.INTEGER
}, { sequelize, modelName: 'comment' });
Post.hasMany(Comment, {
foreignKey: 'commentableId',
......
......@@ -651,29 +651,29 @@ sequelize.sync({ force: true, match: /_test$/ });
Sequelize Models are ES6 classes. You can very easily add custom instance or class level methods.
```js
class User extends Model {}
User.init({ firstname: Sequelize.STRING }, { sequelize });
// Adding a class level method
User.classLevelMethod = function() {
class User extends Model {
// Adding a class level method
static classLevelMethod() {
return 'foo';
};
}
// Adding an instance level method
User.prototype.instanceLevelMethod = function() {
// Adding an instance level method
instanceLevelMethod() {
return 'bar';
};
}
}
User.init({ firstname: Sequelize.STRING }, { sequelize });
```
Of course you can also access the instance's data and generate virtual getters:
```js
class User extends Model {}
User.init({ firstname: Sequelize.STRING, lastname: Sequelize.STRING }, { sequelize });
User.prototype.getFullname = function() {
class User extends Model {
getFullname() {
return [this.firstname, this.lastname].join(' ');
};
}
}
User.init({ firstname: Sequelize.STRING, lastname: Sequelize.STRING }, { sequelize });
// Example:
User.build({ firstname: 'foo', lastname: 'bar' }).getFullname() // 'foo bar'
......
......@@ -33,15 +33,15 @@ class User extends Model {
// we have to declare them here purely virtually
// these will not exist until `Model.init` was called.
public getProjects: HasManyGetAssociationsMixin<Project>;
public addProject: HasManyAddAssociationMixin<Project, number>;
public hasProject: HasManyHasAssociationMixin<Project, number>;
public countProjects: HasManyCountAssociationsMixin;
public createProject: HasManyCreateAssociationMixin<Project>;
public getProjects!: HasManyGetAssociationsMixin<Project>; // Note the null assertions!
public addProject!: HasManyAddAssociationMixin<Project, number>;
public hasProject!: HasManyHasAssociationMixin<Project, number>;
public countProjects!: HasManyCountAssociationsMixin;
public createProject!: HasManyCreateAssociationMixin<Project>;
// You can also pre-declare possible inclusions, these will only be populated if you
// actively include a relation.
public readonly projects?: Project[];
public readonly projects?: Project[]; // Note this is optional since it's only populated when explicitly requested in code
public static associations: {
projects: Association<User, Project>;
......@@ -59,14 +59,22 @@ class Project extends Model {
public readonly updatedAt!: Date;
}
class Address extends Model {
public userId!: number;
public address!: string;
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
}
Project.init({
id: {
type: new DataTypes.INTEGER.UNSIGNED(), // you can omit the `new` but this is discouraged
type: DataTypes.INTEGER.UNSIGNED, // you can omit the `new` but this is discouraged
autoIncrement: true,
primaryKey: true,
},
ownerId: {
type: new DataTypes.INTEGER.UNSIGNED(),
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
},
name: {
......@@ -80,7 +88,7 @@ Project.init({
User.init({
id: {
type: new DataTypes.INTEGER.UNSIGNED(),
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
......@@ -94,16 +102,32 @@ User.init({
}
}, {
tableName: 'users',
modelName: 'user',
sequelize: sequelize, // this bit is important
});
Address.init({
userId: {
type: DataTypes.INTEGER.UNSIGNED,
},
address: {
type: new DataTypes.STRING(128),
allowNull: false,
}
}, {
tableName: 'users',
sequelize: sequelize, // this bit is important
});
// Here we associate which actually populates out pre-declared `association` static and other methods.
User.hasMany(Project, {
sourceKey: 'id',
foreignKey: 'ownerId',
as: 'projects' // this determines the name in `associations`!
});
Address.belongsTo(User, {targetKey: 'id'});
User.hasOne(Address,{sourceKey: 'id'});
async function stuff() {
// Please note that when using async/await you lose the `bluebird` promise context
// and you fall back to native
......@@ -118,7 +142,7 @@ async function stuff() {
});
const ourUser = await User.findByPk(1, {
include: [User.associations.Project],
include: [User.associations.projects],
rejectOnEmpty: true, // Specifying true here removes `null` from the return type!
});
console.log(ourUser.projects![0].name); // Note the `!` null assertion since TS can't know if we included
......@@ -137,12 +161,11 @@ interface MyModel extends Model {
}
// Need to declare the static model so `findOne` etc. use correct types.
// You can also declare all your association stuff in here
type MyModelStatic = typeof Model & {
new (values?: object, options?: BuildOptions): MyModel;
}
// TS can't derive a proper class definition from a `.define` call, therefore we need to cast here.
// TS can't derive a proper class definition from a `.define` call, therefor we need to cast here.
const MyDefineModel = <MyModelStatic>sequelize.define('MyDefineModel', {
id: {
primaryKey: true,
......@@ -158,4 +181,5 @@ function stuffTwo() {
console.log(myModel.id);
});
}
```
......@@ -172,6 +172,10 @@ Model.findAll({
### Query Interface
- `changeColumn` no longer generates constraint with `_idx` suffix. Now Sequelize does not specify any name for constraints thus defaulting to database engine naming. This aligns behavior of `sync`, `createTable` and `changeColumn`.
- `addIndex` aliases options aliases have been removed, use the following instead.
- `indexName` => `name`
- `indicesType` => `type`
- `indexType`/`method` => `using`
### Others
......
......@@ -24,15 +24,15 @@ class User extends Model {
// we have to declare them here purely virtually
// these will not exist until `Model.init` was called.
public getProjects: HasManyGetAssociationsMixin<Project>;
public addProject: HasManyAddAssociationMixin<Project, number>;
public hasProject: HasManyHasAssociationMixin<Project, number>;
public countProjects: HasManyCountAssociationsMixin;
public createProject: HasManyCreateAssociationMixin<Project>;
public getProjects!: HasManyGetAssociationsMixin<Project>; // Note the null assertions!
public addProject!: HasManyAddAssociationMixin<Project, number>;
public hasProject!: HasManyHasAssociationMixin<Project, number>;
public countProjects!: HasManyCountAssociationsMixin;
public createProject!: HasManyCreateAssociationMixin<Project>;
// You can also pre-declare possible inclusions, these will only be populated if you
// actively include a relation.
public readonly projects?: Project[];
public readonly projects?: Project[]; // Note this is optional since it's only populated when explicitly requested in code
public static associations: {
projects: Association<User, Project>;
......@@ -60,12 +60,12 @@ class Address extends Model {
Project.init({
id: {
type: new DataTypes.INTEGER.UNSIGNED(), // you can omit the `new` but this is discouraged
type: DataTypes.INTEGER.UNSIGNED, // you can omit the `new` but this is discouraged
autoIncrement: true,
primaryKey: true,
},
ownerId: {
type: new DataTypes.INTEGER.UNSIGNED(),
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
},
name: {
......@@ -79,7 +79,7 @@ Project.init({
User.init({
id: {
type: new DataTypes.INTEGER.UNSIGNED(),
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
......@@ -98,7 +98,7 @@ User.init({
Address.init({
userId: {
type: new DataTypes.INTEGER.UNSIGNED(),
type: DataTypes.INTEGER.UNSIGNED,
},
address: {
type: new DataTypes.STRING(128),
......
import { Association, HasOne, Model, Sequelize } from 'sequelize';
class MyModel extends Model {
public num: number;
public num!: number;
public static associations: {
other: HasOne;
};
......
......@@ -15,19 +15,19 @@ export class User extends Model {
group: BelongsTo<User, UserGroup>;
};
public id: number;
public username: string;
public firstName: string;
public lastName: string;
public createdAt: Date;
public updatedAt: Date;
public id!: number;
public username!: string;
public firstName!: string;
public lastName!: string;
public createdAt!: Date;
public updatedAt!: Date;
// mixins for association (optional)
public groupId: number;
public group: UserGroup;
public getGroup: BelongsToGetAssociationMixin<UserGroup>;
public setGroup: BelongsToSetAssociationMixin<UserGroup, number>;
public createGroup: BelongsToCreateAssociationMixin<UserGroup>;
public groupId!: number;
public group?: UserGroup;
public getGroup!: BelongsToGetAssociationMixin<UserGroup>;
public setGroup!: BelongsToSetAssociationMixin<UserGroup, number>;
public createGroup!: BelongsToCreateAssociationMixin<UserGroup>;
}
User.init(
......
......@@ -19,20 +19,20 @@ export class UserGroup extends Model {
users: HasMany<UserGroup, User>
};
public id: number;
public name: string;
public id!: number;
public name!: string;
// mixins for association (optional)
public users: User[];
public getUsers: HasManyGetAssociationsMixin<User>;
public setUsers: HasManySetAssociationsMixin<User, number>;
public addUser: HasManyAddAssociationMixin<User, number>;
public addUsers: HasManyAddAssociationsMixin<User, number>;
public createUser: HasManyCreateAssociationMixin<number>;
public countUsers: HasManyCountAssociationsMixin;
public hasUser: HasManyHasAssociationMixin<User, number>;
public removeUser: HasManyRemoveAssociationMixin<User, number>;
public removeUsers: HasManyRemoveAssociationsMixin<User, number>;
public users!: User[];
public getUsers!: HasManyGetAssociationsMixin<User>;
public setUsers!: HasManySetAssociationsMixin<User, number>;
public addUser!: HasManyAddAssociationMixin<User, number>;
public addUsers!: HasManyAddAssociationsMixin<User, number>;
public createUser!: HasManyCreateAssociationMixin<number>;
public countUsers!: HasManyCountAssociationsMixin;
public hasUser!: HasManyHasAssociationMixin<User, number>;
public removeUser!: HasManyRemoveAssociationMixin<User, number>;
public removeUsers!: HasManyRemoveAssociationsMixin<User, number>;
}
// attach all the metadata to the model
......
......@@ -3,10 +3,7 @@
"module": "commonjs",
"target": "es6",
"noEmit": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strict": true,
"baseUrl": ".",
"paths": {
"sequelize": ["../"],
......
......@@ -2,7 +2,7 @@ import { AndOperator, fn, Model, Op, OrOperator, Sequelize, WhereOperators, Wher
import Transaction from '../lib/transaction';
class MyModel extends Model {
public hi: number;
public hi!: number;
}
let where: WhereOptions;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!