Получение результатов от отношения многих ко многим - PullRequest
0 голосов
/ 22 февраля 2020

Я пытаюсь получить результаты от отношения «многие ко многим» (между пользователями и ролями) в распознавателе GraphQL, но я совсем новичок в Sequelize и не понимаю, как правильно запрашивать модель.

Вот моя модель пользователя:

module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('users', {
	id: {
		type: DataTypes.INTEGER(10).UNSIGNED,
		allowNull: false,
		primaryKey: true,
		autoIncrement: true
	},
	name: {
		type: DataTypes.STRING(50),
		allowNull: false
	},
	surname: {
		type: DataTypes.STRING(50),
		allowNull: false
	},
	email: {
		type: DataTypes.STRING(256),
		allowNull: false
	}
}, {
	tableName: 'users',
	timestamps: false,
});

User.associate = function (models) {
	User.belongsToMany(models.roles, {as: 'UserRoles', through: 'users_roles', foreignKey: 'user_id'})
};

return User
};

Вот моя модель ролей:

module.exports = function(sequelize, DataTypes) {
var Role = sequelize.define('roles', {
	id: {
		type: DataTypes.INTEGER(10).UNSIGNED,
		allowNull: false,
		primaryKey: true,
		autoIncrement: true
	},
	name: {
		type: DataTypes.STRING(50),
		allowNull: false
	}
}, {
	tableName: 'roles',
	timestamps: false,
});

Role.associate = function (models) {
	Role.belongsToMany(models.users, {through: 'users_roles', foreignKey: 'role_id'})
};

return Role
};

А вот моя модель таблицы соединений:

module.exports = function(sequelize, DataTypes) {
	return sequelize.define('users_roles', {
		id: {
			type: DataTypes.INTEGER(10).UNSIGNED,
			allowNull: false,
			primaryKey: true,
			autoIncrement: true
		},
		user_id: {
			type: DataTypes.INTEGER(10).UNSIGNED,
			allowNull: false,
			references: {
				model: 'users',
				key: 'id'
			}
		},
		role_id: {
			type: DataTypes.INTEGER(10).UNSIGNED,
			allowNull: false,
			references: {
				model: 'roles',
				key: 'id'
			}
		}
	}, {
		tableName: 'users_roles',
		timestamps: false
	});
};

На данный момент это мое определение GraphQL:

import { gql } from 'apollo-server-express'
import * as db from '../database'

export const typeDefs = gql`
    extend type Query {
        users: [User]
        user(id: ID!): User
    }
    type User {
        id: ID!
        email: String
        name: String
        surname: String
        roles: [String]
    }
`

export const resolvers = {
    Query: {
        users: async () => db.users.findAll(),
        user: async (obj, args, context, info) => db.users.findByPk(args.id),
    },
    User: {
        roles: async (obj, args, context, info) => db.roles.findAll(), // wrong!!
    }
}

Итак, в основном моя проблема заключается в том, что я не понимаю, как написать запрос, чтобы получить список всех ролей, назначенных одному пользователю.

В конце я бы хотел получить (как показано в определении типа пользователя) массив строк, содержащий все имена ролей.

1 Ответ

1 голос
/ 22 февраля 2020

Учитывая экземпляр User, для которого мы правильно определили отношение HasMany или BelongsToMany с другой моделью, мы можем получить массив связанных моделей, вызвав соответствующий метод в нашем экземпляре. Имя метода обычно get[PLURAL_NAME_OF_MODEL] (т. Е. getRoles), но, поскольку вы предоставили опцию as для ваших отношений, метод должен быть getUserRoles. Так что было бы достаточно просто позвонить:

return obj.getUserRoles()

Обратите внимание, что вы также можете нетерпеливо загрузить связанную модель в вашем root распознавателе. В этом случае вы можете полностью опустить преобразователь для roles, если параметр as соответствует имени вашего поля (то есть как roles). Если вы хотите загрузить соответствующие модели, но as не соответствует имени вашего поля (как в этом случае), тогда вы можете вернуть obj[WHATEVER_THE_AS_OPTION_IS] (то есть obj.UserRoles).

Редактировать: С тех пор roles - это список строк, а не объектов, нам нужно сделать что-то вроде:

const roles = await obj.getUserRoles()
return roles.map(role => role.name)
...