Grails多对多关系无法按预期工作

时间:2015-10-11 14:18:00

标签: grails many-to-many dynamic-forms

我是Grails newb,面临着一个困难的多对多关系问题。

这是简化的域类:

class Comment {
    String title
    String comment

    static hasMany = [commentGroups:CommentGroup]

    static constraints = {
        title blank:true
        comment blank:false, maxSize:800
    }

    static mapping = {
        commentGroups cascade: "all-delete-orphan"
    }

}

class CommentGroup {

    String groupTitle

    static hasMany = [comments:Comment]
    static belongsTo = Comment

    static constraints = {
        groupTitle blank:true, nullable:true
    }
}

这是一个使用JS动态构建的表单中的html摘录,请注意我所包含的所有代码都不完整,只是为了给你一个我需要实现的想法:

<form class="m-b-d" role="form" name="comments" id="comments" method="post" action="/rootstofood/comment/save">



  <div class="form-group has-feedback col-sm-12">
    <label for="rating" class="control-label">Give us a star rating?</label>
    <div class="br-wrapper br-theme-bootstrap-stars">
      <select aria-describedby="Rating" name="rating" id="rating" class="form-control input-lg" style="display: none;">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
      </select>
      <div class="br-widget"><a href="#" data-rating-value="1" data-rating-text="1"><span></span></a><a href="#" data-rating-value="2" data-rating-text="2"><span></span></a><a href="#" data-rating-value="3" data-rating-text="3"><span></span></a><a href="#" data-rating-value="4"
        data-rating-text="4"><span></span></a><a href="#" data-rating-value="5" data-rating-text="5"><span></span></a>
        <div class="br-current-rating"></div>
      </div>
    </div>
  </div>

  <div class="form-group has-feedback col-sm-12">
    <label for="commentTitle" class="control-label sr-only">Any short comment header?</label>
    <input aria-describedby="Comment title" placeholder="Any short comment header?" value="" id="commentTitle" name="commentTitle" class="form-control input-lg" maxlength="200">
    <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
    <span class="sr-only" id="commentTitle">(success)</span>
  </div>

  <div class="form-group has-feedback col-sm-12">
    <label for="startComment" class="control-label sr-only">Start comment</label>
    <textarea rows="3" aria-describedby="Start comment" placeholder="Enter start comment" id="startComment" name="startComment" class="form-control input-lg vrequired" maxlength="400"></textarea>
    <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
    <span class="sr-only" id="startComment">(success)</span>
  </div>

  <!-- Children or staff comments area START -->

  <!-- ##### Dynamic area START #### -->
  <div class="col-sm-12" id="comment-groups">

    <div class="panel panel-default p-trbl" data-group-id="0" id="comment-group-0" data-remove-group-id="0">
      <div class="ovh">
        <div class="pull-left"><b>Comment Group: 0</b>
        </div><a class="danger pull-right remove-comment-group" data-remove-group-id="0" href="#"><span class="glyphicon glyphicon-remove-sign"></span> Remove</a>
      </div>
      <div class="panel-body">

        <div class="form-group has-feedback col-sm-12">
          <label for="title" class="control-label sr-only">Any short comment header?</label>
          <input aria-describedby="Comment Group title" placeholder="Any short comment group header?" value="" name="commentGroups[0].groupTitle" class="form-control input-lg" maxlength="200">
          <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
          <span class="sr-only" id="title">(success)</span>
        </div>

        <!-- Children or staff comments area START -->
        <div class="col-sm-12" data-comments-group-id="0" id="comments">

          <div class="panel panel-default p-trbl" data-comment-group-id="GROUP" id="comment-0_0">
            <div class="ovh">
              <div class="pull-left"><b>Staff/Pupil Group/Comment: 0</b>
              </div><a class="danger pull-right remove-comment" data-remove-comment-id="0_0" href="#"><span class="glyphicon glyphicon-remove-sign"></span> Remove</a>
            </div>
            <div class="panel-body">
              <div class="form-group has-feedback col-sm-12">
                <label for="startComment" class="control-label sr-only">Comment</label>
                <textarea id="commentGroups[0].comments[0].startComment" rows="3" aria-describedby="Comment" placeholder="Enter comment" name="commentGroups[0].comments[0].startComment" class="form-control input-lg vrequired" maxlength="400"></textarea>
                <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
                <span class="sr-only" id="comment">(success)</span>
              </div>
              <div class="form-group has-feedback col-sm-10">
                <label for="name" class="control-label sr-only">Name</label>
                <input type="text" aria-describedby="Name" placeholder="Name" name="commentGroups[0].comments[0].name" class="form-control input-lg vrequired" maxlength="30">
                <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
                <span class="sr-only" id="name">(success)</span>
              </div>
              <div class="form-group has-feedback col-sm-2">
                <label for="type" class="control-label sr-only">Comment from</label>
                <select aria-describedby="Type" name="commentGroups[0].comments[0].type" id="type" class="form-control input-lg">
                  <option value="Parent">Parent</option>
                  <option value="Pupil">Pupil</option>
                  <option value="Staff">Staff</option>
                  <option value="KS1">KS1</option>
                  <option value="KS2">KS2</option>
                  <option value="Other">Other</option>
                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="form-group has-feedback col-sm-12">
          <a data-comment-group-id="0" class="add-comment success" href="#"><span class="glyphicon glyphicon-plus-sign"></span> Add another pupil or staff comment</a>
        </div>
        <!-- Children or staff comments area END -->

      </div>
    </div>
  </div>

  <div class="form-group has-feedback col-sm-12">
    <a class="add-group success" href="#"><span class="glyphicon glyphicon-plus-sign"></span> Add another comment group</a>
  </div>

  <!-- Children or staff comments area END -->

  <div class="form-group has-feedback col-sm-12">
    <label for="endComment" class="control-label sr-only">End comment</label>
    <textarea rows="3" aria-describedby="End comment" placeholder="Enter end comment" id="endComment" name="endComment" class="form-control input-lg" maxlength="400"></textarea>
    <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
    <span class="sr-only" id="endComment">(success)</span>
  </div>

  <div class="form-group has-feedback col-sm-2">
    <label for="title" class="control-label sr-only">Title</label>
    <select aria-describedby="Title" name="title" id="title" class="form-control input-lg">
      <option value="Mr">Mr</option>
      <option value="Mrs">Mrs</option>
      <option value="Ms">Ms</option>
      <option value="Miss">Miss</option>
      <option value="Mr &amp; Mrs">Mr &amp; Mrs</option>
    </select>
  </div>

  <div class="form-group has-feedback col-sm-10">
    <label for="firstName" class="control-label sr-only">Name</label>
    <input type="text" aria-describedby="Name" placeholder="Name" id="name" name="name" class="form-control input-lg vrequired" maxlength="60">
    <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
    <span class="sr-only" id="Name">(success)</span>
  </div>

  <div class="form-group has-feedback col-sm-12">
    <label for="jobTitle" class="control-label sr-only">Job title</label>
    <input type="text" aria-describedby="Job title" placeholder="Job title" id="jobTitle" name="jobTitle" class="form-control input-lg" maxlength="60">
    <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
    <span class="sr-only" id="jobTitle">(success)</span>
  </div>

  <div class="form-group has-feedback col-sm-12">
    <label for="organisation" class="control-label sr-only">Organisation</label>
    <input type="text" aria-describedby="Organisation" placeholder="Organisation" id="organisation" name="organisation" class="form-control input-lg" maxlength="60">
    <span aria-hidden="true" class="glyphicon glyphicon-ok form-control-feedback hidden"></span>
    <span class="sr-only" id="organisation">(success)</span>
  </div>

  <div class="form-group has-feedback col-sm-2">
    <label for="type" class="control-label sr-only">Type</label>
    <select aria-describedby="Type" name="type" id="type" class="form-control input-lg">
      <option value="Parent">Parent</option>
      <option value="Pupil">Pupil</option>
      <option value="Staff">Staff</option>
      <option value="KS1">KS1</option>
      <option value="KS2">KS2</option>
      <option value="Other">Other</option>
    </select>
  </div>



  <div class="col-md-12">
    <button class="btn btn-default btn-lg onWht" id="feedback" type="submit"><b>Submit Feedback <span class="glyphicon glyphicon-chevron-right"></span></b>
    </button>
  </div>

</form>

这是我不完整的控制器保存操作,它几乎是开箱即用的:

    def save() {
        def commentInstance = new Comment(params)

        if (!commentInstance.save(flush: true)) {
            render(view: "index", model: [commentInstance: commentInstance])
            return
        }
        render(view: "thankyou")
}

所以从代码中我有一个父域'Comment',它有很多'GroupComment',它有很多'Comment'。

当我构建项目时,我的数据库给了我以下表格:

comment
comment_comment_groups
comment_group

让我感到惊讶,因为我已经规定了多对多的关系所以期待:

comment
comment_comment_groups
comment_group_comments
comment_group

我可能希望Grails在这里做太多工作。因此,当我提交我的评论表单时,数据库中填充了我的父级“评论”,甚至属于“评论”的“评论组”域,但“评论组”评论也没有保存到数据库中。

我意识到我在这里很天真,但我错过了什么?任何人都可以提供帮助,因为我搜索了高低,无法找到类似的情况。我知道有许多多对多的关系示例,但没有一个覆盖我的场景。

与此同时,我将继续搜索。

我的猜测是我需要通过手动处理参数在我的控制器中构建一个更复杂的“保存”动作,但如果有GORM方法可以实现这一点,那就更好了。

期待一些答案......请温柔地对待我: - )

提前致谢。

1 个答案:

答案 0 :(得分:0)

从评论域类删除commentGroups cascade:&#34; all-delete-orphan&#34; 并在CommentGroup中添加映射:comments cascade:&#34; all-delete-orphan&#34;。

新评论(params).save()保存评论组,所有评论都属于该组。