将查询续集到 javascript .map

sequelize query to javascript .map

我正在使用 sequelize 和 .map 函数 return 所有 post 如下。

async function getAll() {
    const posts = await db.Post.findAll({
   
});
    return posts.map(x => postDetails(x));
}



function postDetails(post) {
    const { id, title, postText, accountId, createdAt, updatedAt } = post;
    return { id, title, postText, accountId, createdAt, updatedAt };
}

这一切都很好,但我现在想 return 关于 post 用户的更多信息。所以我试图使用下面的 include 方法来最终获取帐户的用户名。这不会提供错误,但也不会提供用户名。

async function getAll() {
    const posts = await db.Post.findAll({
    
    include: [{
        model: db.Account,
    }]
    
});
    return posts.map(x => postDetails(x));
}



function postDetails(post) {
    const { id, title, postText, accountId, createdAt, updatedAt, username } = post;
    return { id, title, postText, accountId, createdAt, updatedAt, username };
}

从日志中我可以看到它在数组中提供了帐户信息???

  post {
    dataValues: {
      id: 2,
      title: 'test title',
      postText: 'test post content',
      created: 2021-05-04T13:58:08.000Z,
      updated: null,
      accountId: 1,
      account: [account] 

然后我向下钻取以仅包含用户名,但确实收到错误消息:

async function getAll() {
    const posts = await db.Post.findAll({
    
    include: [{
        model: db.Account,
        include: db.Account.username
    }]
    
});
    console.log(posts)
    return posts.map(x => postDetails(x));
}



function postDetails(post) {
    const { id, title, postText, accountId, createdAt, updatedAt, username } = post;
    return { id, title, postText, accountId, createdAt, updatedAt, username };
}

{"message":"Cannot read property 'map' of undefined"}

关系

db.Account.hasMany(db.Post, { onDelete: 'CASCADE' });
db.Post.belongsTo(db.Account);

编辑:我尝试删除 .map 函数并得到相同的错误。如果我删除第二个 include 语句和 map 语句,它 return 是 post 和所有关联的帐户详细信息,但我只想要用户名,然后理想地映射它。

谢谢你的帮助。

您还可以为您的关系设置别名:db.Post.belongsTo(db.Account, { as: 'account' }); 以将帐户作为 Post“属性”(https://sequelize.org/master/manual/assocs.html#association-aliases--amp--custom-foreign-keys)。

试试这个:

async function getAll() {
    const posts = await db.Post.findAll({
    
    include: [{
        association: 'account', // association alias
        attributes: ['username'], // username is just an attribute
        required: true, // inner join instead of left join (post without account are discarded)
    }]
    
});
    console.log(posts)
    return posts.map(x => postDetails(x));
}



function postDetails(post) {
    const { id, title, postText, accountId, createdAt, updatedAt, account } = post;
    return { id, title, postText, accountId, createdAt, updatedAt, username: account.username }; // username is an account attribute
}

在我看来 account: [account] 是一个数组。因此,您可能必须检查 account 数组的第一项才能到达 username 属性:

function postDetails(post) {
    const { 
      id, 
      title, 
      postText, 
      accountId, 
      createdAt, 
      updatedAt, 
      account 
    } = post;

    return { 
      id, 
      title, 
      postText, 
      accountId, 
      createdAt, 
      updatedAt, 

      // Also check that account has an item in it just in case...
      username: account.length > 0 && account[0].username 
    };
}

如果 account 中有多个项目,您可能需要添加额外的检查,具体取决于您期望的数据。

我会为奖励积分做的另一件事是将 postDetails 添加到地图函数,无需传递 x arg:

return posts.map(postDetails);

我觉得这叫点免费风格