Grails — очень простой набор значений коллекции не работает

Контроллер для ошибки:

это метод создания ошибки, я распечатал bugInstance.activities, и в нем был мой объект активности

def create = {
        def bugInstance = new Bug()
        def activity = new Activity(description:"created")

        bugInstance.properties = params
        bugInstance.addToActivities(activity)
        return [bugInstance: bugInstance]
    }

Затем я посмотрел на метод сохранения и напечатал то же самое, и результат нулевой, поэтому каким-то образом он потерял созданную мной активность, и я понятия не имею, почему. Это действительно поведение по умолчанию? Я делаю что-то действительно неправильное, потому что, похоже, нет никаких причин, по которым такой простой фрагмент кода не будет работать.

def save = {

    def bugInstance = new Bug(params)
    println bugInstance.activities
    if (bugInstance.save(flush: true)) {
        flash.message = "${message(code: 'default.created.message', args: [message(code: 'bug.label', default: 'Bug'), bugInstance.id])}"
        redirect(action: "show", id: bugInstance.id)
    }
    else {
        render(view: "create", model: [bugInstance: bugInstance])
    }
}

Я знаю, что могу обойти это, добавив активность в метод сохранения, но почему я теряю активность из create() -> save()


person walnutmon    schedule 19.07.2010    source источник


Ответы (3)


Вы никогда не вызываете save() для нового экземпляра:

def create = {
   def bugInstance = new Bug()
   def activity = new Activity(description:"created")

   bugInstance.properties = params
   bugInstance.addToActivities(activity)
   bugInstance.save()
   return [bugInstance: bugInstance]
}

Вам не нужно сохранять действие, потому что оно будет сохранено транзитивно, так как оно находится в коллекции действий.

person Burt Beckwith    schedule 19.07.2010
comment
Да, это, вероятно, будет работать до тех пор, пока я отправлю постоянный bugInstance (с идентификатором, сгенерированным и сохраненным как его свойство), но тогда ошибки будут сохраняться, когда пользователь переходит на страницу создания, а не когда они фактически выбирают сохранение. Но это указывает на то, что я должен добавить активность в метод контроллера save(). Тем не менее, остается вопрос, как бы вы передавали одно другому в чистом объектно-ориентированном виде? - person walnutmon; 20.07.2010

может показаться глупым вопросом, но вы устанавливаете скрытый параметр или что-то еще в create.gsp с экземпляром ошибки, созданным при создании ?? Я имею в виду, я не вижу ничего плохого в том, что ты здесь делаешь. Как выглядит ваш файл create.gsp?

person mcroteau    schedule 19.07.2010
comment
Я нет, я включил все необходимое. код, насколько мне известно. Grails не передает этот объект через модель, как я ожидал, он просто воссоздается при отправке формы. Но все же должен быть способ OO сделать то, что я пытаюсь здесь - person walnutmon; 20.07.2010

Если вы используете автоматически сгенерированный файл create.gsp, набор действий не будет включен в форму. Конечно, в модели он есть, но на стороне клиента не будет отображаться поле действий. Когда дело доходит до сохранения, становится ясно, что активность потеряна. В зависимости от того, чего вы хотите достичь, вы можете добавить селектор действий в файл create.gsp или (для начала) скрытое поле с описанием ваших действий, но затем в действии сохранения, я думаю, вам нужно обрабатывать параметр действий в любом случае, так как магия Grails не доходит до того, чтобы создать экземпляр Activity для вас. Точно так же, как вы создаете экземпляр самой ошибки в действии сохранения, вы должны создать экземпляр действия и даже сохранить его, если хотите, чтобы оно сохранялось.

Изменить: если вы действительно хотите обойти весь список действий, вы можете использовать индексированные свойства.

В create.gsp добавьте это:

<g:each status="i" var="activity" in="${bugInstance.activities}">
  <!-- one hidden field for each property of each attached activity  -->
  <g:hiddenField
    name="activities[${i}].description"
    value="${activity.description}" />
</g:each>

И в методе сохранения это:

params.activities.each{ activity ->
  bugInstance.addToActivities(new Activity(activity))
}

Но в вашем случае может быть достаточно создать экземпляр одного действия из одного поля.

person hlg    schedule 19.07.2010