Grails привязывает данные к нескольким классам доменов - PullRequest
2 голосов
/ 18 мая 2011

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, я также хотел бы добавить вхождения carroMovel в одном файле save2.Я не уверен, как это сделать, особенно потому, что у класса Carro должен быть идентификатор из класса carroMovel.Любая помощь, пожалуйста?Спасибо.

Я последовал за некоторыми предложениями, и теперь результаты следующие (я еще не обеспокоен ошибкой проверки):

 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 ]

2 голосов
/ 18 мая 2011

Сначала я бы изменил имена ввода на 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 и что правильные значения вводятся в форму без установленного атрибута значения.

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])
}
0 голосов
/ 20 февраля 2013

Для того чтобы Carro смог каскадно сохранить ссылку CarroMovel, CarroMovel требуется belongsTo = Carro, или вам нужно вручную указать hibernate для каскадирования при сохранении, используя что-то вроде этого:

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

Вот документация гибернации о каскадировании: https://docs.jboss.org/hibernate/orm/4.0/javadocs/org/hibernate/metamodel/binding/CascadeType.html

0 голосов
/ 18 мая 2011

Некоторые другие ответы могут быть проще, но я использую эту технику: http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/

0 голосов
/ 18 мая 2011

Если я правильно понимаю ваш вопрос, вы можете попробовать. Сначала отредактируйте нашу форму, включив в нее необходимые поля для класса CarroMovel, * 1001 например *

<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])
  }

Дайте мне знать, если это сработает для вас.

0 голосов
/ 18 мая 2011

Я обычно использую объект команды для такого типа вещей.

В вашем контроллере сделайте что-то вроде этого:

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(){...}), либо вручную в методе контроллера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...