Sequelize:从查询返回的实例方法和属性未定义
Sequelize: Instance Methods and Properties returned from Query are undefined
续集:6.6.2
Mysql2: 2.2.5
我已经像这样定义了我的 Model
并设置了这样的方法:
interface IUserAttributes {
user_id: number;
logon_name: string;
user_password: string;
full_name: string;
disable_user: number;
district_code: number;
created_modified: Date;
}
interface IUserCreationAttributes extends Optional<IUserAttributes, 'user_id'> { }
export class User
extends Model<IUserAttributes, IUserCreationAttributes>
implements IUserAttributes {
public user_id!: number;
public logon_name!: string;
public user_password!: string;
public full_name!: string;
public disable_user!: number;
public district_code!: number;
public created_modified!: Date;
public readonly user_assigned_level: UserAssignedLevel;
public static associations: {
user_assigned_level: Association<User, UserAssignedLevel>
}
public toUserJSON: () => User;
public generateAccessToken: (payload: IUser) => string;
public generateRefreshToken: (payload: IUser) => string;
public getRole: () => 'meter_reader' | 'evaluator' | null;
}
User.prototype.toUserJSON = function () {
const keysToDelete = ['user_password'];
const obj = this.toJSON();
keysToDelete.forEach((key) => delete obj[key]);
return obj;
}
User.prototype.getRole = function (): 'meter_reader' | 'evaluator' {
const userLevel = this.user_assigned_level.user_level_id;
let role = null;
if (userLevel === 13) {
role = 'meter_reader';
} else if (userLevel === 9) {
role = 'evaluator';
}
return role;
}
User.init(
{
user_id: {
autoIncrement: true,
type: DataTypes.SMALLINT,
allowNull: false,
primaryKey: true
},
logon_name: {
type: DataTypes.STRING(20),
allowNull: false
},
user_password: {
type: DataTypes.STRING(20),
allowNull: false
},
full_name: {
type: DataTypes.STRING(100),
allowNull: false
},
disable_user: {
type: DataTypes.TINYINT.UNSIGNED,
allowNull: false,
defaultValue: 0
},
district_code: {
type: DataTypes.CHAR(2),
allowNull: true
},
created_modified: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: literal('CURRENT_TIMESTAMP')
}
},
{
sequelize: DBInstance,
tableName: 'users',
timestamps: false,
underscored: true,
defaultScope: {
attributes: {
exclude: ['user_password']
}
},
scopes: {
withoutPassword: {
attributes: { exclude: ['user_password'] },
}
},
}
);
// foreignKey of Model to target
User.hasOne(UserAssignedLevel, {
foreignKey: 'user_id',
as: 'user_assigned_level' // this determines the name in `associations`
});
当我查询用户并尝试使用我定义的 toUserJSON()
方法时,它失败了
const user = await User.findOne({
include: {
model: UserAssignedLevel,
as: 'user_assigned_level',
where: {
[Op.or]: [
{ user_level_id: 9 },
{ user_level_id: 13 },
]
},
},
where: {
logon_name: username,
disable_user: 0
},
attributes: {
include: ['user_id', 'logon_name', 'user_password', 'disable_user'],
// exclude: ['user_password']
},
});
if (!user) {
return next(new ErrorHandler(401, 'Incorrect credentials.'));
}
const result = user.toUserJSON(); // user.toUserJSON is not a function
当我在控制台中记录 user
实例的值时,它 return 是这样的。
当我尝试访问像 user_id
或 logon_name
这样的 属性 值时,它总是 return 未定义。我必须像 user.getDataValue('user_id')
一样使用 getDataValue()
来访问该字段。
User {
dataValues: {
user_id: 581,
logon_name: 'cha',
full_name: 'CHARISSE SUNGA',
disable_user: 0,
district_code: '9',
created_modified: 2021-03-24T01:52:14.000Z,
user_password: 'èÀ‘\x81k\x8D²pœUìOÌ:\x9D´',
user_assigned_level: UserAssignedLevel {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set(0) {},
_options: [Object],
isNewRecord: false,
user_assigned_level_id: undefined,
user_id: undefined,
user_level_id: undefined,
created_modified: undefined
}
},
_previousDataValues: {
user_id: 581,
logon_name: 'cha',
full_name: 'CHARISSE SUNGA',
disable_user: 0,
district_code: '9',
created_modified: 2021-03-24T01:52:14.000Z,
user_password: 'èÀ‘\x81k\x8D²pœUìOÌ:\x9D´',
user_assigned_level: UserAssignedLevel {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set(0) {},
_options: [Object],
isNewRecord: false,
user_assigned_level_id: undefined,
user_id: undefined,
user_level_id: undefined,
created_modified: undefined
}
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [ [Object] ],
includeNames: [ 'user_assigned_level' ],
includeMap: { user_assigned_level: [Object] },
includeValidated: true,
attributes: [
'user_id',
'logon_name',
'full_name',
'disable_user',
'district_code',
'created_modified',
'user_id',
'logon_name',
'user_password',
'disable_user'
],
raw: true
},
isNewRecord: false,
user_assigned_level: undefined,
user_id: undefined,
logon_name: undefined,
user_password: undefined,
full_name: undefined,
disable_user: undefined,
district_code: undefined,
created_modified: undefined,
toUserJSON: undefined,
generateAccessToken: undefined,
generateRefreshToken: undefined,
getRole: undefined
}
如您所见,dataValues 之外的方法和属性都是未定义的。
对于遇到同样问题的任何人,我设法通过在 class 定义中设置方法来解决问题。
但是,像 this.username
那样直接访问属性仍然 return 未定义。您可以使用 getDataValue
方法 this.getDataValue('username')
或 get
方法 const user = this.get({ plain:true })
访问属性
export class UserAuth
extends Model<IUserAuthAttributes, IUserAuthCreationAttributes>
implements IUserAuthAttributes {
public user_auth_id!: number;
public username!: string;
public password!: string;
public full_name!: string;
public disable_user: number;
public user_level_id!: number;
public created_modified: string | Date;
// Set the method here
getRole() {
const user = this.get({ plain: true });
let role = null;
if (user.user_level_id === 13) {
role = 'meter_reader';
} else if (user.user_level_id === 9) {
role = 'evaluator';
}
return role;
}
}
续集:6.6.2
Mysql2: 2.2.5
我已经像这样定义了我的 Model
并设置了这样的方法:
interface IUserAttributes {
user_id: number;
logon_name: string;
user_password: string;
full_name: string;
disable_user: number;
district_code: number;
created_modified: Date;
}
interface IUserCreationAttributes extends Optional<IUserAttributes, 'user_id'> { }
export class User
extends Model<IUserAttributes, IUserCreationAttributes>
implements IUserAttributes {
public user_id!: number;
public logon_name!: string;
public user_password!: string;
public full_name!: string;
public disable_user!: number;
public district_code!: number;
public created_modified!: Date;
public readonly user_assigned_level: UserAssignedLevel;
public static associations: {
user_assigned_level: Association<User, UserAssignedLevel>
}
public toUserJSON: () => User;
public generateAccessToken: (payload: IUser) => string;
public generateRefreshToken: (payload: IUser) => string;
public getRole: () => 'meter_reader' | 'evaluator' | null;
}
User.prototype.toUserJSON = function () {
const keysToDelete = ['user_password'];
const obj = this.toJSON();
keysToDelete.forEach((key) => delete obj[key]);
return obj;
}
User.prototype.getRole = function (): 'meter_reader' | 'evaluator' {
const userLevel = this.user_assigned_level.user_level_id;
let role = null;
if (userLevel === 13) {
role = 'meter_reader';
} else if (userLevel === 9) {
role = 'evaluator';
}
return role;
}
User.init(
{
user_id: {
autoIncrement: true,
type: DataTypes.SMALLINT,
allowNull: false,
primaryKey: true
},
logon_name: {
type: DataTypes.STRING(20),
allowNull: false
},
user_password: {
type: DataTypes.STRING(20),
allowNull: false
},
full_name: {
type: DataTypes.STRING(100),
allowNull: false
},
disable_user: {
type: DataTypes.TINYINT.UNSIGNED,
allowNull: false,
defaultValue: 0
},
district_code: {
type: DataTypes.CHAR(2),
allowNull: true
},
created_modified: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: literal('CURRENT_TIMESTAMP')
}
},
{
sequelize: DBInstance,
tableName: 'users',
timestamps: false,
underscored: true,
defaultScope: {
attributes: {
exclude: ['user_password']
}
},
scopes: {
withoutPassword: {
attributes: { exclude: ['user_password'] },
}
},
}
);
// foreignKey of Model to target
User.hasOne(UserAssignedLevel, {
foreignKey: 'user_id',
as: 'user_assigned_level' // this determines the name in `associations`
});
当我查询用户并尝试使用我定义的 toUserJSON()
方法时,它失败了
const user = await User.findOne({
include: {
model: UserAssignedLevel,
as: 'user_assigned_level',
where: {
[Op.or]: [
{ user_level_id: 9 },
{ user_level_id: 13 },
]
},
},
where: {
logon_name: username,
disable_user: 0
},
attributes: {
include: ['user_id', 'logon_name', 'user_password', 'disable_user'],
// exclude: ['user_password']
},
});
if (!user) {
return next(new ErrorHandler(401, 'Incorrect credentials.'));
}
const result = user.toUserJSON(); // user.toUserJSON is not a function
当我在控制台中记录 user
实例的值时,它 return 是这样的。
当我尝试访问像 user_id
或 logon_name
这样的 属性 值时,它总是 return 未定义。我必须像 user.getDataValue('user_id')
一样使用 getDataValue()
来访问该字段。
User {
dataValues: {
user_id: 581,
logon_name: 'cha',
full_name: 'CHARISSE SUNGA',
disable_user: 0,
district_code: '9',
created_modified: 2021-03-24T01:52:14.000Z,
user_password: 'èÀ‘\x81k\x8D²pœUìOÌ:\x9D´',
user_assigned_level: UserAssignedLevel {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set(0) {},
_options: [Object],
isNewRecord: false,
user_assigned_level_id: undefined,
user_id: undefined,
user_level_id: undefined,
created_modified: undefined
}
},
_previousDataValues: {
user_id: 581,
logon_name: 'cha',
full_name: 'CHARISSE SUNGA',
disable_user: 0,
district_code: '9',
created_modified: 2021-03-24T01:52:14.000Z,
user_password: 'èÀ‘\x81k\x8D²pœUìOÌ:\x9D´',
user_assigned_level: UserAssignedLevel {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set(0) {},
_options: [Object],
isNewRecord: false,
user_assigned_level_id: undefined,
user_id: undefined,
user_level_id: undefined,
created_modified: undefined
}
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [ [Object] ],
includeNames: [ 'user_assigned_level' ],
includeMap: { user_assigned_level: [Object] },
includeValidated: true,
attributes: [
'user_id',
'logon_name',
'full_name',
'disable_user',
'district_code',
'created_modified',
'user_id',
'logon_name',
'user_password',
'disable_user'
],
raw: true
},
isNewRecord: false,
user_assigned_level: undefined,
user_id: undefined,
logon_name: undefined,
user_password: undefined,
full_name: undefined,
disable_user: undefined,
district_code: undefined,
created_modified: undefined,
toUserJSON: undefined,
generateAccessToken: undefined,
generateRefreshToken: undefined,
getRole: undefined
}
如您所见,dataValues 之外的方法和属性都是未定义的。
对于遇到同样问题的任何人,我设法通过在 class 定义中设置方法来解决问题。
但是,像 this.username
那样直接访问属性仍然 return 未定义。您可以使用 getDataValue
方法 this.getDataValue('username')
或 get
方法 const user = this.get({ plain:true })
export class UserAuth
extends Model<IUserAuthAttributes, IUserAuthCreationAttributes>
implements IUserAuthAttributes {
public user_auth_id!: number;
public username!: string;
public password!: string;
public full_name!: string;
public disable_user: number;
public user_level_id!: number;
public created_modified: string | Date;
// Set the method here
getRole() {
const user = this.get({ plain: true });
let role = null;
if (user.user_level_id === 13) {
role = 'meter_reader';
} else if (user.user_level_id === 9) {
role = 'evaluator';
}
return role;
}
}