Моя цель - условно вернуть значения модели на основе данных, полученных из самих моделей после заполнения.
Это мое текущее решение:
const bcrypt = require("bcryptjs")
const jwt = require("jsonwebtoken")
const moment = require("moment")
const User = require("../../models/user")
const Post = require("../../models/post")
const { checkAuthorSettings, checkFollowingAuthorSettings } = require('../../shared/utility')
login: async ({ email, password }) => {
try {
const user = await User.findOne({ email }).populate([
{
path: 'posts',
model: 'Post',
populate: [
{
path: 'author',
model: 'User',
},
{
path: 'comments',
model: 'Comment',
populate: {
path: 'author',
model: 'User',
},
},
],
},
{
path: 'following',
model: 'User',
populate: {
path: 'posts',
model: 'Post',
populate: [
{
path: 'author',
model: 'User',
},
{
path: 'comments',
model: 'Comment',
populate: {
path: 'author',
model: 'User',
},
},
],
},
},
{
path: 'favourites',
model: 'Post',
populate: [
{
path: 'author',
model: 'User',
},
{
path: 'comments',
model: 'Comment',
populate: {
path: 'author',
model: 'User',
},
},
],
},
])
if (!user) throw new Error("An Account by that Email was not found!")
if (!password) throw new Error("Please enter your password")
const passIsValid = bcrypt.compareSync( password, user.password )
if (!passIsValid) throw new Error("Incorrect Password")
const token = jwt.sign(
{
_id: user._id,
email: user.email,
},
`${process.env.JWT_SECRET}`,
{ expiresIn: "1h" }
)
user.status = "online"
user.logged_in_at = moment().format()
await user.save()
return {
...user._doc,
token,
token_expiry: 1,
email: user.settings.display_email ? user.email : "",
website: user.settings.display_website ? user.website : "",
password: null,
posts: await checkAuthorSettings(user.posts),
following: await checkFollowingAuthorSettings(user.following),
favourites: await checkAuthorSettings(user.favourites),
info: JSON.stringify(user._doc.info),
geolocation: JSON.stringify(user._doc.geolocation),
settings: JSON.stringify(user._doc.settings),
}
} catch (err) {
throw err
}
},
утилита. js:
const checkAuthorSettings = array => {
return array.map(post => {
return {
...post._doc,
author: {
...post._doc.author._doc,
email: post._doc.author._doc.settings.display_email ? post._doc.author._doc.email : "",
website: post._doc.author._doc.settings.display_website ? post._doc.author._doc.website : "",
}
}
})
}
const checkFollowingAuthorSettings = array => {
return array.map(followed => {
return {
...followed._doc,
posts: checkAuthorSettings(followed.posts)
}
})
}
exports.checkAuthorSettings = checkAuthorSettings
exports.checkFollowingAuthorSettings = checkFollowingAuthorSettings
Я сейчас просматриваю каждый массив в User, что, как мне кажется, далеко не самый эффективный способ добиться этого.
Есть ли у кого-нибудь лучшее решение, чем это?