如何使用 ColdFusion 2018/Lucee 创建网格输出以显示来自两个查询的数据 5.x
How do I create grid output to display data from two queries using ColdFusion 2018/Lucee 5.x
我有 table 权限、table 角色和映射 table。我想为网站管理员创建一个 GUI,以便能够添加新角色并为该角色分配权限。目前它是在数据库中完成的,因此可能会出现用户错误。
为了简单起见,假设我们有四个角色,SuperAdmin、Admin、Manager 和 User。权限为创建、读取、更新、删除。在下图中,SuperAdmin 和 Admin 与 Manager 和 User 匹配(用户错误的产物,以及为什么我想创建 GUI 但我离题了)。
目前,我的输出为每个角色显示一行,而理想情况下,角色只会显示一次,并且会为相应的权限勾选相应的复选框,类似于以下内容:
这是我的 CF 代码,但我不知道如何处理它来做我想做的事。
<cfquery name="securityGroups" datasource="#application.support#">
Select
r.roleLabel,
r.roleID,
p.permName,
p.permID
From
npermissions p Inner Join
nrole_npermission_map rp On rp.permissionID = p.permID Inner Join
nroles r On rp.roleID = r.roleID
</cfquery>
<cfquery name="securityPermissions" datasource="#application.support#">
Select
p.permName,
p.permID
From
npermissions p
</cfquery>
<table id="datatables" class="datatables">
<thead>
<tr>
<th>Role</th>
<cfoutput query="securityPermissions">
<th>#securityPermissions.permName#</th>
</cfoutput>
</tr>
</thead>
<tbody>
<cfoutput query="securityGroups" group="roleID">
<tr>
<td>#securityGroups.roleLabel#</td>
<cfoutput>
<td>
<input type="checkbox" name="permID" value="#securityPermissions.permID#" <cfif securityGroups.permID eq securityPermissions.permID>checked</cfif> >#securityPermissions.permname# (#securityGroups.permID# eq #securityPermissions.permID#)
</td>
</cfoutput>
</tr>
</cfoutput>
</tbody>
</table>
使用上面的代码,这会产生以下输出,这是我能够获得的最接近我想要的输出。显示了正确的权限,但未选中复选框并且未显示某些权限。
我想我记得几年前在 easycfm 上读过一些关于教程或论坛的内容。
如果源 table 很小,一个简单的方法是将交叉 + 外连接组合到 return 所有可能的值。然后将查询输出“分组”到行中。交叉连接有利于生成“所有组合”,但 table 大小很重要。连接 2 tables,每行 1000 行,每行产生 100 万行!所以大小是一个重要的考虑因素。
<!--- Returns ALL available roles and permissions --->
<cfquery name="qGridData">
SELECT r.roleID
, r.RoleLabel
, p.permName
, p.permID
, ISNULL(m.permissionID, 0) AS AssignedPermID
FROM nRoles r
CROSS JOIN nPermissions p
LEFT JOIN nRole_nPermission_Map m
ON m.permissionID = p.permID
AND m.roleID = r.RoleID
ORDER BY r.RoleLabel, p.PermName
</cfquery>
<cfquery name="qGridLabels">
SELECT p.permName
FROM nPermissions p
ORDER BY p.PermName
</cfquery>
<table>
<cfoutput query="qGridData">
<th>#permName#</th>
</cfoutput>
</tr>
<cfoutput query="qGridData" group="roleLabel">
<tr><td>#roleLabel# (id=#roleID#)</td>
<input type="hidden" name="roleID" value="#roleID#">
<cfoutput>
<td><input type="checkbox" name="roleID_permissions_#roleID#" value="#permID#" <cfif AssignedPermID>checked</cfif>> </td>
</cfoutput>
</tr>
</cfoutput>
</table>
另一种选择是使用某种枢轴table。在数据方面,它们比第一个选项更紧凑。虽然动态内容不太灵活。我不熟悉应该适用于大多数数据库的 MariaDB implementation of pivot tables, but :
SELECT r.RoleID
, r.RoleLabel
, MAX(CASE WHEN p.PermName = 'Read' THEN m.PermissionID ELSE 0 END) AS ReadAllowed
, MAX(CASE WHEN p.PermName = 'Read' THEN p.PermID ELSE 0 END) AS ReadID
, MAX(CASE WHEN p.PermName = 'Create' THEN m.PermissionID ELSE 0 END) AS CreateAllowed
, MAX(CASE WHEN p.PermName = 'Create' THEN p.PermID ELSE 0 END) AS CreateID
, MAX(CASE WHEN p.PermName = 'Delete' THEN m.PermissionID ELSE 0 END) AS DeleteAllowed
, MAX(CASE WHEN p.PermName = 'Delete' THEN p.PermID ELSE 0 END) AS DeleteID
, MAX(CASE WHEN p.PermName = 'Update' THEN m.PermissionID ELSE 0 END) AS UpdateAllowed
, MAX(CASE WHEN p.PermName = 'Update' THEN p.PermID ELSE 0 END) AS UpdateID
FROM nRoles r
CROSS JOIN nPermissions p
LEFT JOIN nRole_nPermission_Map m
ON m.permissionID = p.permID
AND m.roleID = r.RoleID
GROUP BY
r.RoleID
, r.RoleLabel
ORDER BY r.RoleLabel
我有 table 权限、table 角色和映射 table。我想为网站管理员创建一个 GUI,以便能够添加新角色并为该角色分配权限。目前它是在数据库中完成的,因此可能会出现用户错误。
为了简单起见,假设我们有四个角色,SuperAdmin、Admin、Manager 和 User。权限为创建、读取、更新、删除。在下图中,SuperAdmin 和 Admin 与 Manager 和 User 匹配(用户错误的产物,以及为什么我想创建 GUI 但我离题了)。
目前,我的输出为每个角色显示一行,而理想情况下,角色只会显示一次,并且会为相应的权限勾选相应的复选框,类似于以下内容:
这是我的 CF 代码,但我不知道如何处理它来做我想做的事。
<cfquery name="securityGroups" datasource="#application.support#">
Select
r.roleLabel,
r.roleID,
p.permName,
p.permID
From
npermissions p Inner Join
nrole_npermission_map rp On rp.permissionID = p.permID Inner Join
nroles r On rp.roleID = r.roleID
</cfquery>
<cfquery name="securityPermissions" datasource="#application.support#">
Select
p.permName,
p.permID
From
npermissions p
</cfquery>
<table id="datatables" class="datatables">
<thead>
<tr>
<th>Role</th>
<cfoutput query="securityPermissions">
<th>#securityPermissions.permName#</th>
</cfoutput>
</tr>
</thead>
<tbody>
<cfoutput query="securityGroups" group="roleID">
<tr>
<td>#securityGroups.roleLabel#</td>
<cfoutput>
<td>
<input type="checkbox" name="permID" value="#securityPermissions.permID#" <cfif securityGroups.permID eq securityPermissions.permID>checked</cfif> >#securityPermissions.permname# (#securityGroups.permID# eq #securityPermissions.permID#)
</td>
</cfoutput>
</tr>
</cfoutput>
</tbody>
</table>
使用上面的代码,这会产生以下输出,这是我能够获得的最接近我想要的输出。显示了正确的权限,但未选中复选框并且未显示某些权限。
我想我记得几年前在 easycfm 上读过一些关于教程或论坛的内容。
如果源 table 很小,一个简单的方法是将交叉 + 外连接组合到 return 所有可能的值。然后将查询输出“分组”到行中。交叉连接有利于生成“所有组合”,但 table 大小很重要。连接 2 tables,每行 1000 行,每行产生 100 万行!所以大小是一个重要的考虑因素。
<!--- Returns ALL available roles and permissions --->
<cfquery name="qGridData">
SELECT r.roleID
, r.RoleLabel
, p.permName
, p.permID
, ISNULL(m.permissionID, 0) AS AssignedPermID
FROM nRoles r
CROSS JOIN nPermissions p
LEFT JOIN nRole_nPermission_Map m
ON m.permissionID = p.permID
AND m.roleID = r.RoleID
ORDER BY r.RoleLabel, p.PermName
</cfquery>
<cfquery name="qGridLabels">
SELECT p.permName
FROM nPermissions p
ORDER BY p.PermName
</cfquery>
<table>
<cfoutput query="qGridData">
<th>#permName#</th>
</cfoutput>
</tr>
<cfoutput query="qGridData" group="roleLabel">
<tr><td>#roleLabel# (id=#roleID#)</td>
<input type="hidden" name="roleID" value="#roleID#">
<cfoutput>
<td><input type="checkbox" name="roleID_permissions_#roleID#" value="#permID#" <cfif AssignedPermID>checked</cfif>> </td>
</cfoutput>
</tr>
</cfoutput>
</table>
另一种选择是使用某种枢轴table。在数据方面,它们比第一个选项更紧凑。虽然动态内容不太灵活。我不熟悉应该适用于大多数数据库的 MariaDB implementation of pivot tables, but
SELECT r.RoleID
, r.RoleLabel
, MAX(CASE WHEN p.PermName = 'Read' THEN m.PermissionID ELSE 0 END) AS ReadAllowed
, MAX(CASE WHEN p.PermName = 'Read' THEN p.PermID ELSE 0 END) AS ReadID
, MAX(CASE WHEN p.PermName = 'Create' THEN m.PermissionID ELSE 0 END) AS CreateAllowed
, MAX(CASE WHEN p.PermName = 'Create' THEN p.PermID ELSE 0 END) AS CreateID
, MAX(CASE WHEN p.PermName = 'Delete' THEN m.PermissionID ELSE 0 END) AS DeleteAllowed
, MAX(CASE WHEN p.PermName = 'Delete' THEN p.PermID ELSE 0 END) AS DeleteID
, MAX(CASE WHEN p.PermName = 'Update' THEN m.PermissionID ELSE 0 END) AS UpdateAllowed
, MAX(CASE WHEN p.PermName = 'Update' THEN p.PermID ELSE 0 END) AS UpdateID
FROM nRoles r
CROSS JOIN nPermissions p
LEFT JOIN nRole_nPermission_Map m
ON m.permissionID = p.permID
AND m.roleID = r.RoleID
GROUP BY
r.RoleID
, r.RoleLabel
ORDER BY r.RoleLabel