【发布时间】:2019-09-20 11:33:56
【问题描述】:
我有一个使用 Sequelize/mysql 的 GraphQL/Apollo 服务器。我的 GraphQL 类型(Employee、Contractor)每个都实现了一个 Person 接口。我的数据库模型包含一个员工、承包商和事件表。我希望我的 Person Type 与 Events 有“多重”关系。而我的事件类型“属于”员工或承包商的人员类型。
我猜它与事件类型中的person_id 字段有关。我可以让它在没有单个表“员工”上的界面并将person_id更改为employee_id的情况下工作。所以我猜它只是不知道如何区分 Employee 和 Contractor 来引用该表?
//typeDefs.js
const typeDefs = gql`
type Event {
id: ID!
person_id: ID!
location: String!
escort: String!
}
interface Person {
id: ID!
first_name: String!
last_name: String!
department_company: String!
events: [Event]
}
type Employee implements Person {
id: ID!
first_name: String!
last_name: String!
department_company: String!
events: [Event]
employee_sh_id: String
}
type Contractor implements Person {
id: ID!
first_name: String!
last_name: String!
department_company: String!
events: [Event]
escort_required: Boolean!
}
//Employee model
module.exports = (sequelize, DataTypes) => {
const Employee = sequelize.define('Employee', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
department_company: DataTypes.STRING,
emplyee_sh_id: DataTypes.STRING
}, {});
Employee.associate = function(models) {
Employee.hasMany(models.Event);
};
return Employee;
};
// Contractor model
module.exports = (sequelize, DataTypes) => {
const Contractor = sequelize.define('Contractor', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
department_company: DataTypes.STRING,
escort_required: DataTypes.BOOLEAN,
}, {});
Contractor.associate = function(models) {
Contractor.hasMany(models.Event);
};
return Contractor;
};
// Event model
module.exports = (sequelize, DataTypes) => {
const Event = sequelize.define(
"Event",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
person_id: DataTypes.INTEGER,
location: DataTypes.STRING,
escort: DataTypes.STRING
},
{}
);
Event.associate = function(models) {
Event.belongsTo(models.Employee),
Event.belongsTo(models.Contractor)
};
return Event;
};
// resolvers.js
const resolvers = {
Query: {
async employee(root, { id }, { models }) {
return models.Employee.findByPk(id);
},
async contractor(root, { id }, { models }) {
return models.Contractor.findByPk(id);
},
async employees(root, args, { models }) {
return models.Employee.findAll();
},
async contractors(root, args, { models }) {
return models.Contractor.findAll();
},
async event(root, { id }, { models }) {
return models.Event.findByPk(id);
},
async events(root, args, { models }) {
return models.Event.findAll();
}
},
Mutation: {
async addEmployee(
root,
{
first_name,
last_name,
department_company,
employee_sh_id
},
{ models }
) {
return models.Employee.create({
first_name,
last_name,
department_company,
employee_sh_id
});
},
async addContractor(
root,
{
first_name,
last_name,
department_company,
escort_required,
},
{ models }
) {
return models.Contractor.create({
first_name,
last_name,
department_company,
escort_required,
});
},
async addEvent(
root,
{ person_id, location, escort },
{ models }
) {
return models.Event.create({
person_id,
location,
escort
});
},
Person: {
__resolveType: person => {
if (person.employee) {
return "Employee";
}
return "Contractor";
}
},
Employee: {
events: (parent, args, context, info) => parent.getEvents(),
},
Contractor: {
events: (parent, args, context, info) => parent.getEvents(),
}
};
【问题讨论】:
-
你好。感谢您在问题中包含相关代码。不幸的是,说“没有界面也能工作”并不能真正描述具体的问题。如果您在运行服务器或执行查询时看到特定的错误消息,请将其包含在您的问题中。否则,请详细描述您看到的预期行为和实际的意外行为。
-
另外,如果界面的工作方式有问题,最好看看您是如何为界面实现
resolveType函数的。 -
@DanielRearden 感谢丹尼尔,抱歉信息不足。我已经添加了 resolver.js 文件中的信息。我只是说我在实现接口之前让它工作了。所以只是一个员工到事件的关系。我只是不确定如何与可以来自两个不同表的人员类型建立“有一个”关系。
-
我应该将员工和承包商的数据存储在同一个表中吗?当我想获得员工时,我只查询员工字段而不是承包商独有的字段?这对我来说似乎是错误的,但可行。
-
对不起,我现在明白了。感谢您澄清您的问题。
标签: javascript sql graphql sequelize.js apollo-server