Итак, я разрабатываю REST API, и недавно появилась одна проблема solid. У меня есть несколько сущностей с отношением «один ко многим», в основном очень упрощенная схема будет выглядеть так:
Так что же мне делать здесь есть FeedEntry сущность, которая имеет поле 'feed' (идентификатор), который указывает на Feed сущность, и то же самое для Feed , имеющей поле 'space', которое является идентификатором соответствующей пробел сущности.
Проблема возникает, когда я пытаюсь получить конкретный FeedEntry по идентификатору, поскольку существует специальное условие.
Каждый объект Space имеет массив идентификаторов пользователей-членов и поле 'owner', которое также является идентификатором пользователя. Мне нужно определить, является ли пользователь, который запрашивает FeedEntry , членом / владельцем Space , который содержит соответствующий Feed (и запрошенный FeedEntry должен указывать на Feed с его полем «feed»). Пока что мое «лучшее» решение для такого рода проверки выглядит следующим образом:
async (id, { req: { user } }) => {
const entry = await FeedEntry.findById(id);
const parentFeed = await Feed.findById(entry.feed);
const isMember = parentFeed && await Space.exists({
_id: parentFeed.space,
$or: [{ members: user._id }, { owner: user._id }]
});
if (!isMember)
return Promise.reject('Issuer has no access to this feed entry.');
}
На мой взгляд, это выглядит довольно неуклюже, и я уверен, что есть гораздо лучший способ сделать что-то подобное с некоторые расширенные функции Mon goose и / или MongoDB. Любая помощь будет оценена.
UPD
Код схемы
const SpaceSchema = new Schema({
_id: { type: String, default: generate },
name: { type: String, required: true, unique: true },
owner: { type: String, required: true },
members: [{ type: String }]
});
const FeedSchema = new Schema({
_id: { type: String, default: generate },
name: { type: String, required: true },
owner: { type: String, required: true },
space: { type: String, required: true },
entries: [{ type: String }]
});
const FeedEntrySchema = new Schema({
_id: { type: String, default: generate },
author: { type: String, required: true },
header: { type: String, required: true },
content: { type: String, required: true },
feed: { type: String, required: true },
createdAt: { type: Date, default: new Date().toISOString() },
edited: { type: Boolean, default: false }
});
Образцы документов
FeedEntry:
_id: "SNdmSx6G"
createdAt: 2020-01-04T18:33:35.117+00:00
edited: false
author: "ADPKXAHm"
header: "Test entry 2"
content: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commo..."
feed: "c6zarBHg"
__v:0
Feed :
_id: "c6zarBHg"
entries:
Array
0: "1v40fOpj"
1: "SNdmSx6G"
name: "Tst 2.3"
owner: "6FyfkAGX"
space: "b_mBKcd4"
__v: 0
Пробел:
_id: "b_mBKcd4"
members:
Array
0: "ADPKXAHm"
name: "Tst 2"
owner: "6FyfkAGX"
__v: 0