Grails数据绑定多个域类

时间:2011-05-17 23:37:57

标签: grails data-binding

HI。我有这个课程:

class Carro {

    String name
    String marca
    String matricula

    static constraints = {
        name(nullable:false, blank:false)
    }

    static mapping = {
        version false
    }
}

class CarroMovel {
    String move
    String rodas
    String espelhos
    Carro carro

    static hasMany = [carros: Carro]

    static constraints = {
        move(nullable:false, blank:false)
    }

    static mapping = {
        version false
    }
}

控制器:

class CarroController{
def save2 = {

        def carroInstance = new Carro()
        carroInstance.name = params.name
        carroInstance.marca = params.marca
        carroInstance.matricula = params.matricula

        if (carroInstance.save(flush: true)) {
            redirect(uri:"/home.gsp")
        }
        else {
            render(view: "/testeAdd", model: [carroInstance: carroInstance])
        }

    }

视图testeAdd.gsp

<g:form controller="carro" action="save2">
<h1>Add New Carro Record</h1>
<p>Basic Information</p>

<label>Name
<span class="small">as</span>
</label>
<input type="text" name="name" value="${carroInstance?.name}" /><br>

<label>Marca
<span class="small">as</span>
</label>
<input type="text" name="marca" value="${carroInstance?.marca}" /><br

  <label>Matricula
<span class="small">as</span>
</label>
<input type="text" name="matricula" value="${carroInstance?.matricula}" /><br>


<g:submitButton name="save" value="Save" id="oneone"/>


<div class="spacer"></div>
  </g:form>

                <g:hasErrors bean="${carroInstance}">
            <div class="errors">
                <g:renderErrors bean="${carroInstance}" as="list" />
            </div>
            </g:hasErrors>

这很好用。现在我希望能够绑定多个域类的数据。因此,与我的gsp文件中的当前代码一起,我还想在同一个save2中添加carroMovel的出现次数。我不知道该怎么做,特别是因为类Carro需要有一个carroMovel类的id。有什么帮助吗?谢谢。

我提出了一些建议,现在结果如下(我还不关心错误验证):

 def save3 = {

        def carroInstance = new Carro()
        def carroMovelInstance = new CarroMovel()

        carroInstance.name = params.carro.name
        carroInstance.marca = params.carro.marca
        carroInstance.matricula = params.carro.matricula

        carroMovelInstance.move = params.carroMovel.move
        carroMovelInstance.rodas = params.carroMovel.rodas
        carroMovelInstance.espelhos = params.carroMovel.espelhos

        carroInstance.save()
        carroMovelInstance.carro = carroInstance
        carroMovelInstance.save()

    }

<g:form controller="carro" action="save3">
<h1>Add New Conference Record</h1>
<p>Basic Information</p>

<label>Name
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.name" value="${carroInstance?.name}" /><br>

<label>Marca
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.marca" value="${carroInstance?.marca}" /><br

  <label>Matricula
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.matricula" value="${carroInstance?.matricula}" /><br>

<label>Move
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.move" value="${carroMovelInstance?.move}" /><br>

<label>Rodas
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.rodas" value="${carroMovelInstance?.rodas}" /><br>

<label>Espelho
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.espelho" value="${carroMovelInstance?.espelho}" /><br>

<g:submitButton name="save" value="Save" id="addConference"/>

Carro对象保存在数据库中,而且,CarroMovel没有任何反应,并且没有保存,我无法弄明白。

5 个答案:

答案 0 :(得分:2)

首先,我将输入名称更改为carro.name,carro.marca,carroMovel.move,...以便按名称区分它们。

<input type="text" name="carro.name"/><br>
<input type="text" name="carro.marca"/><br>
<input type="text" name="carroMovel.move"/><br>

这样做的好处是控制器中的绑定可以使用标准的Grails方式完成,并且在没有设置value属性的情况下在表单中输入正确的值。

carro.properties = params.carro 
carroMovel.properties = params.carroMovel

在控制器操作中,您还可以保存并链接Carro和CarroMovel实例。

carro.save()
carroMovel.carro = carro
carroMovel.save()
if(carroMovel.hasErrors(){
  render(view: 'save3', model: [carro: carro, carroMovel.carroMovel])
}

答案 1 :(得分:0)

我通常使用命令对象来处理这类事情。

在您的控制器中执行以下操作:

class CarroController {

  def show = {
    [cmd: new MyCommand()]
  }

  def save2 = { MyCommand cmd ->
    def carro = cmd.carro

    if (carro.save()) {
      cmd.movel.carro = carro
      if (cmd.movel.save()) {
        redirect uri: 'home.gsp'
      } else {
        // show form again
        render view: 'show', model:[cmd:cmd]
      }
    } else {
      // show form again
      render view: 'show', model:[cmd:cmd]
    }
  }

  // same file or some other class file
  class MyCommand {
      Carro carro
      CarroMovel movel
  }
}

您还需要稍微调整一下表单......

你有“Carro”字段的地方像这样引用它们:

<input type="text" name="carro.matricula" value="${cmd.carro?.matricula}" />

你有“CarroMovel”字段,如下所示:

<input type="text" name="movel.rodas" value="${cmd.movel?.rodas}" />

这段代码可能不完全正确(我没有测试过),但应该让你走上正确的道路。而不是引用命令对象中的对象,您可以只拥有要绑定的字段,然后通过辅助方法(def buildCarro(){...})或在控制器中手动构建实际的域对象。方法

答案 2 :(得分:0)

如果我理解你的问题,你可以尝试一下。 首先,编辑我们的表单以包含CarroMovel类的必要字段, e.g

<label>Move
<span class="small">as</span>
</label>
<input type="text" name="move" value="${carroMovelInstance?.move}" />

然后

在你的save2操作中,

def carroInstance = new Carro()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula

def carroMovelInstance = new CarroMovel()
carroMovelInstance.name = params.move
carroMovelInstance.marca = params.rodasa
carroMovelInstance.matricula = params.espelhos
carroMovelInstance.carro = carroInstance

由于Carro不属于CarroMovel,因此carroMovelInstance不会级联到carroInstance,因此您需要在保存其拥有实例之前单独保存每个实例。

carroMovelInstance.carro.save()
if (carroMovelInstance.save(flush: true)) {
        redirect(uri:"/home.gsp")
    }
    else {
        render(view: "/testeAdd", model: [carroInstance: carroInstance, carroMovelInstance:carroMovelInstance])
  }

如果有效,请告诉我。

答案 3 :(得分:0)

其他一些答案可能更简单,但我一直在使用这种技术: http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/

答案 4 :(得分:0)

为了让Carro级联保存CarroMovel参考,CarroMovel需要belongsTo = Carro,或者您需要手动告诉hibernate在保存后使用以下内容进行级联:

class CarroMovel{
  static mapping = { 
   carro cascade: 'all' 
  }
}

这是关于级联的hibernate文档: https://docs.jboss.org/hibernate/orm/4.0/javadocs/org/hibernate/metamodel/binding/CascadeType.html