Добавление дочерних элементов в объект домена до создания объекта домена

(Извините, если это нубский вопрос, я не смог найти ответы на ссылку в Grails)

У меня есть следующая heirarchy домена:

Пользователь > (имеет много) Survey > (имеет много) SurveyQuestion > (имеет много) SurveyQuestionResponse

Это два из вышеперечисленных:

class Survey {

    String surveyName

    static hasMany = [questions: SurveyQuestion]
    static belongsTo = [user:User]
    static constraints = {
    }
}

class SurveyQuestion {

    String question

    static hasMany = [responses : SurveyQuestionResponse]
    static belongsTo = [survey:Survey]

    static constraints = {
    }
}

Когда я создаю опрос, я сначала вижу такой экран:

опрос

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

опросный вопрос

Но это требует проведения опроса, который еще не завершен.

Вопрос: Нужно ли сначала создавать и сохранять опрос, затем редактировать его и добавлять вопросы опроса (каждый из которых необходимо создать и сохранить по отдельности, прежде чем я смогу создавать ответы), или есть способ добавить дочерние объекты, как я? создание родительских объектов?

Я хочу использовать динамические леса, поэтому мне не нужно создавать контроллеры и представления вручную.

Вопросы и ответы полностью независимы и не будут повторно использоваться в иерархии.

4 ответа

Решение

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

class CreateSurveyCommand {
     String surveyName
     List<SurveyQuestion> surveyQuestions = 
         org.apache.commons.collections.list.LazyList.decorate(
             new ArrayList(), 
             new org.apache.commons.collections.functors.InstantiateFactory(SurveyQuestion.class))
}

По мнению (при условии index.gsp) у вас есть что-то вроде:

<g:textField name="surveyName" value="${cmd?.question}" />
<g:each in="${cmd.surveyQuestions}" var="surveyQuestion" status="i">
    <g:textField
        name="surveyQuestions[i].question" 
        value="${cmd?.surveyQuestions[i].question}" />
</g:each>
<g:actionSubmit action="addQuestion"/>

Имея addQuestion действие в вашем контроллере:

def addAction(CreateSurveyCommand cmd) {
    cmd.surveyQuestions.add(new SurveyQuestion())
    render(view:"index", model: [cmd: cmd])
}

Редактирование это еще одна тема, но работает так же.

Посмотрите на это сообщение в блоге:

http://blog.andresteingress.com/2012/06/29/groovy-2-0-love-for-grails-command-objects

Используя этот пользовательский интерфейс, вы должны создавать, сохранять и добавлять. Лучшим подходом является создание пользовательского интерфейса master / detail. Вы можете увидеть этот подход здесь:

https://github.com/leadVisionary/Grails-Survey-Module

http://programmingitch.blogspot.com/2009/10/data-binding-for-one-to-many.html

http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/

http://java.dzone.com/articles/creating-master-detail-forms

http://kapilpandit.wordpress.com/2009/02/25/complex_form_grails/

Если вы объявите questions как List в Survey класс, то ваши взгляды смогут получить к ним доступ по индексу.

List questions
static hasMany = [questions: SurveyQuestion]

В вашей форме GSP вы можете использовать что-то вроде этого:

<g:textField
    name="questions[0].question"
    value="${surveyInstance?.questions?.size() > 0 ? surveyInstance?.questions[0]?.question : ''}"/>

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

Если вам действительно нужно использовать динамические леса, вы можете переопределить отдельные представления или шаблоны, используемые для создания представления. В качестве альтернативы вы можете использовать плагин fields для визуализации входных данных для questions имущество.

Я создал простое приложение, и в этот момент все, кажется, просто работает. Я ожидал, чтобы написать PropertyEditor реализация, чтобы расширить список, но кажется, что Grails 2.1 сделает это за вас.

Изменение порядка или удаление вопросов потребует больше экспериментов, но обновление вопросов работает, то есть текст вопроса меняется, а не новый SurveyQuestion экземпляр создается.

Если вы собираетесь повторно использовать вопросы... возможно, вам не следует использовать ownTo =[survey:Survey]

Затем, если у вас нет этой связи, вы можете создать шаблон для создания вопросов и добавить их в коллекцию вопросов в объекте опроса, прежде чем сохранять его!

Другие вопросы по тегам