在 sequelize 的多对多关系中为联结 table 设置别名
Set an alias for the junction table in a many to many relationship in sequelize
如果标题令人困惑,我深表歉意,我不确定在这里使用什么术语。
基本上,我有三个(技术上有四个,但第四个几乎与 user.model.js 相同)模型:
user.model.js
'use strict';
const {Model} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
User.belongsToMany(models.Item, {
through: 'UserItems',
as: 'items',
foreignKey: 'userId',
otherKey: 'itemId'
});
}
}
User.init({
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING,
allowNull: false
}
}, {
sequelize,
modelName: 'User',
paranoid: true,
associations: true
});
return User;
};
item.model.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Item extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
Item.belongsToMany(models.Guest, {
through: {
model: 'GuestItems',
unique: false
},
constraints: false,
as: 'guests',
foreignKey: 'itemId',
otherKey: 'guestId'
});
Item.belongsToMany(models.User, {
through: {
model: 'UserItems',
unique: false
},
constraints: false,
as: 'users',
foreignKey: 'itemId',
otherKey: 'userId'
});
}
}
Item.init({
dexId: {
allowNull: true,
type: DataTypes.INTEGER,
defaultValue: null
},
name: {
type: DataTypes.STRING,
unique: true,
allowNull: false
},
description: DataTypes.STRING,
filename: DataTypes.STRING,
firstSeen: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null
},
firstAcquired: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null
},
}, {
sequelize,
modelName: 'Item',
paranoid: true
});
return Item;
};
useritems.model.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class UserItems extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
};
UserItems.init({
userId: DataTypes.INTEGER,
itemId: DataTypes.INTEGER,
seen: DataTypes.BOOLEAN,
owned: DataTypes.BOOLEAN
}, {
sequelize,
modelName: 'UserItems',
});
return UserItems;
};
在我的控制器中,我有
User.findByPk(id,
{
include: { model: db.Item, as: 'items', through: { attributes: ['seen']} },
order: [[sequelize.literal('"items"."dexId"'), 'ASC']],
})
.then(data => {
console.log(data.items);
res.status(200).json({ items: data.items});
})
.catch(err => {
console.log(err);
res.status(204).json({ items: []});
});
现在这工作得很好,除了 'seen' 和 'owned' 列被添加到一个名为 UserItems 的附加 object。
returned 项目的示例:
Item {
dataValues: {
id: 65,
dexId: null,
name: 'Fiona29',
description: 'Quasi et sint.',
filename: 'http://placeimg.com/640/480/animals',
firstSeen: 2021-08-25T18:25:52.125Z,
firstAcquired: 2021-08-26T02:36:05.250Z,
createdAt: 2021-08-25T02:29:07.511Z,
updatedAt: 2021-08-26T02:36:05.249Z,
deletedAt: null,
UserItems: [UserItems]
},
_previousDataValues: {
id: 65,
dexId: null,
name: 'Fiona29',
description: 'Quasi et sint.',
filename: 'http://placeimg.com/640/480/animals',
firstSeen: 2021-08-25T18:25:52.125Z,
firstAcquired: 2021-08-26T02:36:05.250Z,
createdAt: 2021-08-25T02:29:07.511Z,
updatedAt: 2021-08-26T02:36:05.249Z,
deletedAt: null,
UserItems: [UserItems]
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [Array],
includeNames: [Array],
includeMap: [Object],
includeValidated: true,
raw: true,
attributes: undefined
},
isNewRecord: false,
UserItems: UserItems {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set(0) {},
_options: [Object],
isNewRecord: false
}
},
这不太适合我使用数据的目的 - 基本上,还有一个访客 table 与项目 table 具有等效的 many-to-many 关系,并且它的连接 table 称为 GuestItems。因此,当我搜索客人时 - 上面的结果吐出相同的数据,但使用 GuestItems 而不是 UserItems。
我希望 发生的是 UserItems/GuestItems 重命名为 Items。或者理想情况下,只需将 UserItems/GuestItems table 中的 'seen' 和 'owned' 列添加到其余结果中,而不是它自己的 'UserItems/GuestItems' 属性。
这可以用 Sequelize 完成吗?我真的不想在 return.
中添加另一个重命名 object 的步骤
要仅重命名 UserItems table,您可以在“through”选项中使用“as”选项:
User.findByPk(id,
{
include: { model: db.Item, as: 'items', through: { as: "Items", attributes: ['seen', 'owned']} },
order: [[sequelize.literal('"items"."dexId"'), 'ASC']],
})
.then(data => {
console.log(data.items);
res.status(200).json({ items: data.items});
})
.catch(err => {
console.log(err);
res.status(204).json({ items: []});
});
这应该return项为:
Item {
dataValues: {
id: 65,
dexId: null,
name: 'Fiona29',
description: 'Quasi et sint.',
filename: 'http://placeimg.com/640/480/animals',
firstSeen: 2021-08-25T18:25:52.125Z,
firstAcquired: 2021-08-26T02:36:05.250Z,
createdAt: 2021-08-25T02:29:07.511Z,
updatedAt: 2021-08-26T02:36:05.249Z,
deletedAt: null,
Items: {
seen: false,
owned: false
}
}
至于将它们直接保存在 'Item' 中不确定是否可以使用 sequelize 查找器来完成,您可能需要编写自己的原始 SQL 查询以加入 'seen' 和'UserItems' 上的 'owned' 列 'Item'。
如果标题令人困惑,我深表歉意,我不确定在这里使用什么术语。
基本上,我有三个(技术上有四个,但第四个几乎与 user.model.js 相同)模型:
user.model.js
'use strict';
const {Model} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
User.belongsToMany(models.Item, {
through: 'UserItems',
as: 'items',
foreignKey: 'userId',
otherKey: 'itemId'
});
}
}
User.init({
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING,
allowNull: false
}
}, {
sequelize,
modelName: 'User',
paranoid: true,
associations: true
});
return User;
};
item.model.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Item extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
Item.belongsToMany(models.Guest, {
through: {
model: 'GuestItems',
unique: false
},
constraints: false,
as: 'guests',
foreignKey: 'itemId',
otherKey: 'guestId'
});
Item.belongsToMany(models.User, {
through: {
model: 'UserItems',
unique: false
},
constraints: false,
as: 'users',
foreignKey: 'itemId',
otherKey: 'userId'
});
}
}
Item.init({
dexId: {
allowNull: true,
type: DataTypes.INTEGER,
defaultValue: null
},
name: {
type: DataTypes.STRING,
unique: true,
allowNull: false
},
description: DataTypes.STRING,
filename: DataTypes.STRING,
firstSeen: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null
},
firstAcquired: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null
},
}, {
sequelize,
modelName: 'Item',
paranoid: true
});
return Item;
};
useritems.model.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class UserItems extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
};
UserItems.init({
userId: DataTypes.INTEGER,
itemId: DataTypes.INTEGER,
seen: DataTypes.BOOLEAN,
owned: DataTypes.BOOLEAN
}, {
sequelize,
modelName: 'UserItems',
});
return UserItems;
};
在我的控制器中,我有
User.findByPk(id,
{
include: { model: db.Item, as: 'items', through: { attributes: ['seen']} },
order: [[sequelize.literal('"items"."dexId"'), 'ASC']],
})
.then(data => {
console.log(data.items);
res.status(200).json({ items: data.items});
})
.catch(err => {
console.log(err);
res.status(204).json({ items: []});
});
现在这工作得很好,除了 'seen' 和 'owned' 列被添加到一个名为 UserItems 的附加 object。
returned 项目的示例:
Item {
dataValues: {
id: 65,
dexId: null,
name: 'Fiona29',
description: 'Quasi et sint.',
filename: 'http://placeimg.com/640/480/animals',
firstSeen: 2021-08-25T18:25:52.125Z,
firstAcquired: 2021-08-26T02:36:05.250Z,
createdAt: 2021-08-25T02:29:07.511Z,
updatedAt: 2021-08-26T02:36:05.249Z,
deletedAt: null,
UserItems: [UserItems]
},
_previousDataValues: {
id: 65,
dexId: null,
name: 'Fiona29',
description: 'Quasi et sint.',
filename: 'http://placeimg.com/640/480/animals',
firstSeen: 2021-08-25T18:25:52.125Z,
firstAcquired: 2021-08-26T02:36:05.250Z,
createdAt: 2021-08-25T02:29:07.511Z,
updatedAt: 2021-08-26T02:36:05.249Z,
deletedAt: null,
UserItems: [UserItems]
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [Array],
includeNames: [Array],
includeMap: [Object],
includeValidated: true,
raw: true,
attributes: undefined
},
isNewRecord: false,
UserItems: UserItems {
dataValues: [Object],
_previousDataValues: [Object],
_changed: Set(0) {},
_options: [Object],
isNewRecord: false
}
},
这不太适合我使用数据的目的 - 基本上,还有一个访客 table 与项目 table 具有等效的 many-to-many 关系,并且它的连接 table 称为 GuestItems。因此,当我搜索客人时 - 上面的结果吐出相同的数据,但使用 GuestItems 而不是 UserItems。
我希望 发生的是 UserItems/GuestItems 重命名为 Items。或者理想情况下,只需将 UserItems/GuestItems table 中的 'seen' 和 'owned' 列添加到其余结果中,而不是它自己的 'UserItems/GuestItems' 属性。
这可以用 Sequelize 完成吗?我真的不想在 return.
中添加另一个重命名 object 的步骤要仅重命名 UserItems table,您可以在“through”选项中使用“as”选项:
User.findByPk(id,
{
include: { model: db.Item, as: 'items', through: { as: "Items", attributes: ['seen', 'owned']} },
order: [[sequelize.literal('"items"."dexId"'), 'ASC']],
})
.then(data => {
console.log(data.items);
res.status(200).json({ items: data.items});
})
.catch(err => {
console.log(err);
res.status(204).json({ items: []});
});
这应该return项为:
Item {
dataValues: {
id: 65,
dexId: null,
name: 'Fiona29',
description: 'Quasi et sint.',
filename: 'http://placeimg.com/640/480/animals',
firstSeen: 2021-08-25T18:25:52.125Z,
firstAcquired: 2021-08-26T02:36:05.250Z,
createdAt: 2021-08-25T02:29:07.511Z,
updatedAt: 2021-08-26T02:36:05.249Z,
deletedAt: null,
Items: {
seen: false,
owned: false
}
}
至于将它们直接保存在 'Item' 中不确定是否可以使用 sequelize 查找器来完成,您可能需要编写自己的原始 SQL 查询以加入 'seen' 和'UserItems' 上的 'owned' 列 'Item'。