在 Grails 中动态创建可用脚手架的菜单

Dynamically creating a menu of available scaffoldings in Grails

我的 Grails 应用程序中有一堆模型 classes,所有这些都是为了它们各自的数据库表的动态脚手架。对于应用程序的索引,我想要一个包含所有这些脚手架的菜单,以便在添加新模型时更新菜单。

是否有任何自动的 Grails 方法可以做到这一点,或者我是否坚持使用一堆 g:link 为每个 class 静态输入的朴素索引视图来吸引用户到他们各自的 CRUD 视图?

您可以像这样简单地构建它们的列表:

<ul>
    <g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }">
    <li><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
    </g:each>
</ul>

此代码取自默认 index.gsp 的旧 Grails 1.3x 项目。不确定它在最新版本的 Grails 中是否仍然有效,但它至少应该让您了解可以动态执行的操作。

更新 正如 Jeff Scott Brown 所指出的那样,这将包括 ALL 控制器,无论是否是脚手架,以及那些由插件提供的控制器。从理论上讲,您可以进一步从 grailsApplication.controllerClasses 中过滤结果 类,检查它们的包(假设您的域在一个或多个已知包中)and/or 如果它们是脚手架(static scaffold = true).

作为对 Joshua 回答的扩展,下面应该为您提供至少在 grails 3 中的脚手架控制器列表。

<g:each var="c" in="${grailsApplication.controllerClasses.findAll{ it.isReadableProperty('scaffold') } }">
    <li><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
</g:each>

编辑

根据评论中的要求,要获得 table 名称,您需要访问 sessionFactory,您需要将其注入到控制器中,如下所示将为您提供域映射名称到域 table 名称。

控制器

class YourController {

    def sessionFactory

    def index() {
        def scaffoldedTables = grailsApplication.controllerClasses.findAll{ it.isReadableProperty( 'scaffold' ) }.collectEntries {
            [(it.name): sessionFactory.getClassMetadata(it.getPropertyValue( 'scaffold', Object.class )).tableName]
        }

        [scaffoldedTables: scaffoldedTables]
    }
}

gsp

<g:each var="c" in="${scaffoldedTables}">
    <li><g:link controller="${c.key}">${c.value}</g:link></li>
</g:each>