Динамическое создание меню доступных каркасов в Grails

У меня есть куча классов моделей в моем приложении Grails, и все они предназначены для динамического создания шаблонов соответствующих таблиц базы данных. Для индекса приложения я хотел бы иметь меню всех этих лесов, чтобы при добавлении новой модели меню обновлялось.

Есть ли какой-либо автоматический способ Grails сделать это, или я застрял в создании наивного представления индекса с кучей g:link, статически типизированных для каждого класса, чтобы направить пользователя к их соответствующим представлениям CRUD?


person Straightfw    schedule 23.01.2019    source источник


Ответы (2)


В качестве дополнения к ответу Джошуа следующее должно дать вам список контроллеров с каркасом, по крайней мере, в 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>

РЕДАКТИРОВАТЬ

Как указано в комментариях, чтобы получить имя таблицы, вам понадобится доступ к sessionFactory, который вам нужно будет внедрить в контроллер, что-то вроде следующего даст вам карту имени домена в имя таблицы домена.

Контроллер

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]
    }
}

гсп

<g:each var="c" in="${scaffoldedTables}">
    <li><g:link controller="${c.key}">${c.value}</g:link></li>
</g:each>
person Mike W    schedule 23.01.2019
comment
Есть ли дополнительные условия для этого? Я попробовал это в простом приложении с двумя образцами моделей с каркасами, и хотя у них обоих есть static scaffold = [name] в своих контроллерах, только они отображаются в списке ссылок, сгенерированных с помощью предоставленного кода :( - person Straightfw; 24.01.2019
comment
Извините, что использовал find, а не findAll, попробуйте с обновленным примером - person Mike W; 24.01.2019
comment
Отлично, работает как шарм, большое спасибо! Если позволите, последний вопрос в примечании: есть ли способ отобразить имя, которое переводится в Grails? Я имею в виду, если у меня есть каркасный контроллер с именем AaaBbbController, есть ли простой способ отобразить aaa_bbb (или AAA_BBB, не имеет значения) в сгенерированном списке ссылок, а не полное имя, которое вызывает {c.fullName}? - person Straightfw; 24.01.2019
comment
Вы хотите, чтобы имя таблицы в БД не было именем домена? - person Mike W; 24.01.2019
comment
Да, так что я получаю список ссылок в виде {DB_name}, а не {packageName}.{controllerName} - person Straightfw; 25.01.2019
comment
Большое спасибо! Но должно ли это работать как есть, просто добавив его в IndexController? Мне нужно, чтобы список был виден в индексе, который обрабатывается index.gsp, поэтому я сделал grails create-controller Index, добавил код, затем добавил второй фрагмент в views/index.gsp, но это приводит к тому, что список вообще не отображается - он пуст. Почему это так? - person Straightfw; 25.01.2019
comment
Какой index.gsp? я предполагаю, что их будет много, вы имеете в виду тот, который находится в корне /grails-app/views? если да, то нет, достаточно просто перенаправить на другой контроллер в ваших UrlMappings, что-то вроде "/"(controller: "home"), где home - это имя вашего контроллера. - person Mike W; 25.01.2019
comment
Ах, забыл сопоставить с контроллером в UrlMappings и все еще имел базовое сопоставление с представлением индекса, правда! Решено, всем большое спасибо за помощь :) - person Straightfw; 25.01.2019

Вы можете просто составить их список следующим образом:

<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>

Этот код был взят из старого проекта Grails 1.3x из стандартного index.gsp. Не уверен, что он все еще работает в последних версиях Grails, но, по крайней мере, он должен дать вам представление о том, что вы можете сделать, чтобы быть динамичным.

ОБНОВЛЕНИЕ Как отметил Джефф Скотт Браун, это будет включать в себя ВСЕ контроллеры, встроенные или нет, а также те, которые предоставляются плагинами. Теоретически вы можете дополнительно отфильтровать результирующие классы из grailsApplication.controllerClasses, проверив их на наличие их пакетов (при условии, что ваш домен находится в известном пакете или пакетах) и/или если они сформированы (static scaffold = true).

person Joshua Moore    schedule 23.01.2019
comment
Обратите внимание, что предлагаемое решение будет отображать больше, чем все контроллеры с каркасом. Этот код будет перечислять все контроллеры, созданные или нет, и будет включать контроллеры, предоставляемые плагинами, а не только контроллеры, связанные с классами моделей в приложении. - person Jeff Scott Brown; 23.01.2019
comment
Большое спасибо за помощь! - person Straightfw; 28.01.2019