【问题标题】:Grails dynamic scaffold with hasMany: is it a bug or am I misconfiguring?带有hasMany的Grails动态脚手架:是错误还是我配置错误?
【发布时间】:2010-10-23 19:33:27
【问题描述】:

我是 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 不允许我添加,因为我是新手,但如果有帮助,我很乐意向他们展示另一种方式。

【问题讨论】:

    标签: grails has-many


    【解决方案1】:

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

    【讨论】:

      【解决方案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>
      

      换句话说,对于这种极端情况,默认的创建视图会省略小部件以正确显示多选列表。当我复制和粘贴丢失的代码时,动态脚手架控制器将其拾取并按预期持久化。所以,这绝对是视图生成代码中的一个错误。

      【讨论】:

        【解决方案3】:

        是的,默认的脚手架会在子类的创建/编辑页面中放置一个父选择器。

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

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

        static hasMany = [teams:Team]
        

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

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

        【讨论】:

        • 感谢您的回复比尔。我认为我的例子可能更好的地方是,我希望一名球员成为多个球队的成员。它实际上是多对多而不是一对多。这就是为什么我在 Player 上没有 belongsTo 的原因,但我现在看到我碰巧选择的用例可能会引起混乱。对我来说奇怪的是,多选按预期显示在编辑屏幕上,但不在创建屏幕上。这种不一致让我认为这是动态脚手架中的一个错误,但我几乎不会犯错误(显然)
        • 嗯,直到 v1.1,Grails 才真正支持多对多,需要您手动创建关系对象并自己管理互惠。我还没有使用 v1.1,所以我不能评论它的脚手架默认值,但它在编辑时显示而不是创建时显示的事实确实看起来很可疑。您可以尝试在 Nabble 的 Grails 电子邮件列表上发帖:nabble.com/grails---user-f11861.html
        • 我已经编辑了我的回复,以考虑到您的多对多方面
        猜你喜欢
        • 2011-06-25
        • 2013-11-06
        • 1970-01-01
        • 2013-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-08
        相关资源
        最近更新 更多