开发者

Prisma result processing into single object

I'm working on a nextjs 13 project with prisma ORM with MongoDB. Currently I am trying to fetch roles with permissions for admin role matrix. This is the Role model schema.

model Role {
  id          String   @id @default(auto()) @map("_id") @db.ObjectId
  name        String   @unique
  userIDs     String[] @db.ObjectId
  users       User[]   @relation(fields: [userIDs], references: [id开发者_开发百科])
  permissions String[]

  @@map("roles")
}

When fetching the records I'd like to process them a little. Running this query returns such result.

const roles = await prisma.role.findMany({
    select: {
        name: true,
        permissions: true,
    }
})
console.log(roles);
 [
  { name: 'User', permissions: [ 'permissions.user.view.dashboard' ] },
  {
    name: 'Admin',
    permissions: [
      'permissions.admin.view.dashboard',
      'permissions.user.view.dashboard'
    ]
  }
]

I need the results in one object with role name prepended to the permission like so

{
    'User.permissions.user.view.dashboard',
    'Admin.permissions.user.view.dashboard',
    'Admin.permissions.admin.view.dashboard'
}

So my question is how would I do this? Preferably directly in prisma, but if it's not possible javascript will do.


You can use the map() method to transform the roles array into the desired object. The map() method takes a callback function as its argument, which will be called for each element in the array. This callback function can be used to transform each element in the array into the desired format.

Here is an example of how you could use the map() method to transform the roles array:

const roles = await prisma.role.findMany({
  select: {
    name: true,
    permissions: true,
  }
});

const processedRoles = roles.map((role) => {
  const newPermissions = role.permissions.map((permission) => {
    return `${role.name}.${permission}`;
  });
  return newPermissions;
});

console.log(processedRoles);

The map() method will return a new array containing the transformed elements. In this case, the new array will contain the permission strings with the role name prepended to the permission.

You can then use the reduce() method to combine the elements in the processedRoles array into a single object. The reduce() method takes a callback function as its argument, which will be called for each element in the array. This callback function can be used to combine the elements in the array into a single object.

Here is an example of how you could use the reduce() method to combine the elements in the processedRoles array into a single object:

const roles = await prisma.role.findMany({
  select: {
    name: true,
    permissions: true,
  }
});

const processedRoles = roles.map((role) => {
  const newPermissions = role.permissions.map((permission) => {
    return `${role.name}.${permission}`;
  });
  return newPermissions;
});

const result = processedRoles.reduce((acc, current) => {
  return [...acc, ...current];
}, {});

console.log(result);

The reduce() method will return a single object containing all of the elements in the processedRoles array. This object will have the desired format, with the role name prepended to each permission.

You can also use the flat() method to flatten the processedRoles array before passing it to the reduce() method. This will avoid the need to use the spread operator (...) in the reduce() method.

Here is an example of how you could use the flat() and reduce() methods together to transform the roles array:

const roles = await prisma.role.findMany({
  select: {
    name: true,
    permissions: true,
  }
});

const processedRoles = roles.map((role) => {
  const newPermissions = role.permissions.map((permission) => {
    return `${role.name}.${permission}`;
  });
  return newPermissions;
});

const result = processedRoles.flat().reduce((acc, current) => {
  return [...acc,

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜