Динамический каркас Grails с hasMany: это ошибка или я неправильно конфигурирую? - PullRequest
7 голосов
/ 05 мая 2009

Я новичок Grails и сталкиваюсь с чем-то, что кажется ошибкой, но вполне возможно, что я не все настраиваю правильно.

У меня есть два простых предметных класса:

   class Player {

        String firstName
        String lastName

        static constraints = {
            firstName(blank:false)
            lastName(blank:false)
        }
        String toString() { lastName + ", " + firstName }
    }

и

class Team {

    String mascot;
    static hasMany = [players:Player]

    static constraints = {
        mascot(blank:false)
    }
}

У меня есть контроллеры для обоих, которые ничего не делают, кроме динамического каркаса этих двух классов доменов.

Но даже когда у меня есть список игроков в моей БД, я не получаю для них поле с несколькими вариантами выбора при создании новой команды.

Тем не менее, множественный выбор появляется, когда я иду редактировать команду

Это ошибка в динамических лесах для новых предметов, я неправильно понимаю, как это должно работать, или есть что-то еще, что я должен объявить здесь?

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

Ответы [ 3 ]

2 голосов
/ 07 мая 2009

Я наконец понял это и хотел передать то, что я сделал, на случай, если кто-то еще столкнется с этим.

Когда я сгенерировал представления для Team, блок формы в edit.gsp выглядит так:

    <input type="hidden" name="id" value="${teamInstance?.id}" />
                <input type="hidden" name="version" value="${teamInstance?.version}" />
                <div class="dialog">
                    <table>
                        <tbody>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="mascot">Mascot:</label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean:teamInstance,field:'mascot','errors')}">
                                    <input type="text" id="mascot" name="mascot" value="${fieldValue(bean:teamInstance,field:'mascot')}"/>
                                </td>
                            </tr> 

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="players">Players:</label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean:teamInstance,field:'players','errors')}">
                                    <g:select name="players"
from="${Player.list()}"
size="5" multiple="yes" optionKey="id"
value="${teamInstance?.players}" />

                                </td>
                            </tr> 

                        </tbody>
                    </table>
                </div>
                <div class="buttons">
                    <span class="button"><g:actionSubmit class="save" value="Update" /></span>
                    <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
                </div>
            </g:form>

но блок формы в create.gsp выглядит так:

<g:form action="save" method="post" >
                <div class="dialog">
                    <table>
                        <tbody>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="mascot">Mascot:</label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean:teamInstance,field:'mascot','errors')}">
                                    <input type="text" id="mascot" name="mascot" value="${fieldValue(bean:teamInstance,field:'mascot')}"/>
                                </td>
                            </tr> 

                        </tbody>
                    </table>
                </div>
                <div class="buttons">
                    <span class="button"><input class="save" type="submit" value="Create" /></span>
                </div>
        </g:form>

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

1 голос
/ 28 сентября 2010

Я столкнулся с той же проблемой при использовании текущей версии (v1.3.4) Grails. Пришлось вручную изменить create.gsp

1 голос
/ 05 мая 2009

Да, стандартные леса помещают родительский селектор на дочернюю страницу «создать / редактировать».

Полагаю, так было проще. Это не должен быть множественный выбор, просто выпадающий одиночный выбор, так как это один-ко-многим.

Как вы уже объяснили, вам нужно больше отношений "многие ко многим", вы можете попробовать добавить:

static hasMany = [teams:Team]

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

Если вы используете Grails pre-v1.1, отношения «многие ко многим» напрямую не поддерживаются, поэтому даже добавление статического hasMany выше не будет полным решением, так как вам нужно будет управлять добавлением в другой список, когда вы добавляете в одном направлении. Я еще не использовал v1.1, поэтому я не могу говорить о том, что необходимо для указания в нем «многие ко многим».

...