автоматическое приращение целочисленного поля в Grails

У меня есть поле int displayOrder = 1 в объекте домена Grails, и я хотел бы увеличивать его на 1 каждый раз, когда объект домена сохраняется.

Если у меня есть объект домена Widget, который имеет отношение «один ко многим» с Pix, каждый раз, когда Widget получает новый Pix, Pix должен увеличивать displayOrder.

Что было бы наиболее разумным способом сделать это? Желательно, чтобы счет начинался с 1, чтобы свести к минимуму путаницу, когда кто-то хочет изменить порядок отображения. Я думал о том, чтобы просто продублировать идентификатор, но тогда мы, возможно, смотрим на displayOrder 1123, за которым следует 1169 и т. Д., Так что это не практичный вариант.

Коллекция пикселей, принадлежащих Widget, представляет собой sortedSet.


person vector    schedule 20.01.2012    source источник
comment
Можете ли вы поделиться своим кодом того, как вы создаете Pix и назначаете их Widget? Похоже, вы пытаетесь создать виджет, затем первый пиксель, который вы ассоциируете с ним, - это displayOrder = 1, затем следующий пикс, который вы связываете с ним, - displayOrder = 2. Это правильно?   -  person Jarred Olson    schedule 20.01.2012
comment
... да, именно так.   -  person vector    schedule 20.01.2012


Ответы (2)


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

class Widget {
    static hasMany = [pixes: Pix]
    ...
}
class Pix {
    static belongsTo = [widget: Widget]

    static namedQueries = {
        selectMaxDisplayOrderForWidget { widgetInstance ->
            eq('widget', widgetInstance)
            projections {
                max('displayOrder')
            }
            uniqueResult = true
        }
    }
    ...
}

Потом:

def widget = retrieveOrCreateWidget()
def pix = new Pix(propertyA: "A", ..., displayOrder: Pix.selectMaxDisplayOrderForWidget(widget).list(), widget: widget)

Если вы хотите повторно инициализировать номера порядка отображения после удаленного Pix, чтобы они были последовательными для Widget, согласно вашему комментарию к @Jarred Olson, вы могли бы сделать:

Pix.findAllByWidgetAndDisplayOrderGreaterThan(widget, deletedPixDisplayOrder, [sort:'displayOrder',order:'asc']).eachWithIndex { pixInstance, idx ->
    pixInstance.displayOrder = deletedPixDisplayOrder + idx
    pixInstance.save()
}
person schmolly159    schedule 20.01.2012

Тогда я бы предположил, что ваш код выглядит примерно так:

class Widget {
    static hasMany = [pixes: Pix]
    ...
}
class Pix {
    static belongsTo = [widget: Widget]
    ...
}


def widget = retrieveOrCreateWidget()
def pix = new Pix(propertyA: "A", ..., displayOrder: 1, widget: widget)
pix.save()
widget.addToPixes(pix)
widget.save()

Вы можете определить displayOrder по размеру пикселей:

def widget = retrieveOrCreateWidget()
def pix = new Pix(propertyA: "A", ..., displayOrder: widget.pixes.size() + 1, widget: widget)

РЕДАКТИРОВАТЬ:

Если все, что вам нужно сделать, это иметь возможность отсортировать пиксели виджета по времени их создания, вы можете добавить dateCreated в Pix. Это автоматически устанавливается Grails при создании Pix. Тогда вам не нужно будет увеличивать / уменьшать значение при добавлении и удалении.

person Jarred Olson    schedule 20.01.2012
comment
... вот о чем я думаю. Мне также пришло в голову, что мне нужно будет настроить displayOrder для других пикселей, когда один будет удален. Я думаю о том, чтобы просто уменьшить все значения выше удаленного на 1. - person vector; 20.01.2012