带有hasMany的Grails动态脚手架:它是一个bug还是我错误配置?

时间:2009-05-05 03:06:28

标签: grails has-many

我是Grails noob并遇到了一些似乎是个bug的东西,但完全有可能我没有正确配置所有内容。

我有两个简单的域类:

   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 个答案:

答案 0 :(得分:2)

我终于明白这一点,并希望传递我所做的,以防其他人遇到它。

当我为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 :(得分:1)

是的,默认的脚手架将父选择器放在子类的“创建/编辑页面”中。

我猜这对他们来说更容易。它不应该是一个多选,只是一个下拉单选,因为它是一对多。

正如您所解释的,您想要更多的多对多关系,您可以尝试添加:

static hasMany = [teams:Team]

到您的Player类。我发现Grails在双向关系方面做得更好。在构建搜索查询时也很有用,并且不需要超过您已经需要的一个关系表。

如果您使用的是Grails pre-v1.1,则不直接支持多对多关系,因此即使添加上面的静态hasMany也不是完整的解决方案,因为您需要管理添加添加到一个方向时到另一个列表。我还没有使用v1.1,所以我不能谈论在其中指定多对多所需的内容。

答案 2 :(得分:1)

我使用Grails的当前版本(v1.3.4)遇到了同样的问题。不得不手动修改create.gsp