#grails #grails-orm #domain-model
#grails #grails-orm #модель домена
Вопрос:
Я разрабатываю систему, в которой сообщения / обсуждения между пользователями могут быть обновлены, чтобы стать билетами. В одном конкретном месте я пытаюсь создать необязательные отношения «один к одному», но сталкиваюсь с определенными проблемами. Ниже приведена сокращенная версия объектов, находящихся в центре внимания.
Правила:
- Сообщение может стать тикетом, если требуется. (необязательно)
- У билета должен быть Post. (обязательно)
Post.groovy
class Post {
String title
String description
String postedBy
Ticket ticket
static hasMany = [comments: Comment]
static constraints = {
title(blank:false)
description(blank:false)
postedBy(blank:false)
ticket (nullable:true,unique:true)
}
}
Ticket.groovy
class Ticket {
String title
String description
String postedBy
Post post
static hasMany = [responses: Response]
static constraints = {
title(blank:false)
description(blank:false)
postedBy(blank:false)
post (nullable:false,unique:true)
}
}
В какой-то степени это работает. Я могу:
- Создайте сообщение, оставив атрибут ticket нулевым, если и когда сообщение будет обновлено, чтобы стать билетом
- Я могу явно установить атрибут ticket сообщения, чтобы он указывал на родительский билет.
Однако это сопоставление не применяется на уровне домена. Это оставляет место для ситуации, когда Ticket1 указывает на Post1, но Post1 вместо этого указывает на Ticket2.
Я попытался использовать a static hasOne = [post: Post]
в классе Ticket, но позже узнал, что он требует наличия a static belongsTo = [ticket: Ticket]
в классе Post, и это становится обязательным отношением 1 к 1, что не то, что я ищу.
Есть ли способ добиться этого необязательного сопоставления 1 к 1 в этом сценарии? Любые указатели были бы наиболее полезными.
Комментарии:
1. Пожалуйста, закройте вопрос, если ответ на него вас удовлетворит. Спасибо! 🙂
2. Это не работает. Я не думаю, что 1-1 можно создать. Вероятно, я должен закрыть его как неопровержимый?
Ответ №1:
Вы могли бы рассмотреть возможность создания пользовательского средства проверки, например
class Post {
// Other fields
Ticket ticket
static constraints = {
// Other constraints
ticket (nullable:true,unique:true, validator: { val, obj ->
if(val) {
return val.post == obj
}
})
}
}
Решит ли это вашу проблему?
Комментарии:
1. Привет, спасибо за ваше решение! Это работает (с небольшим внесенным изменением) и лучше, чем предыдущая ситуация, поскольку теперь есть проверка хотя бы на одном конце. Однако теперь все еще существует вероятность того, что я установлю правильный аргумент ticket в Post (поскольку средство проверки применяет его), но затем вернусь к Ticket и изменю объект Post, на который он указывает. Мне просто интересно, есть ли какой-либо способ обеспечить его соблюдение с обоих концов, но я думаю, что нет? 🙁
2. Как насчет другой проверки на другом конце? Это должно быть возможно?
3. Как вы пришли? Есть ли шанс, что вы закроете этот вопрос?
4. Привет, извините за задержку. Я пытался использовать валидатор на другом конце, но это создает конфликт, поскольку одно из значений должно быть установлено перед другим; продолжая попытки, вы скоро узнаете о результате.