Вопросы о реализации отношений и ограничений класса Domain в Grails - PullRequest
1 голос
/ 15 июля 2010

Используя ArgoUML, я очень быстро создал это тривиальное представление нескольких классов Домена (Person, Store, Product) и их отношений. Модель UML http://img411.imageshack.us/img411/715/soquestion.png

Я борюсь с реализацией отношений. Ниже был мой первоначальный подход к домену Person, но мне кажется, что я упускаю что-то важное.

class PersonToPerson {
    Person from
    Person to
    String relation

    static constraints = {
         relation(inList:["Friend to", "Enemy of", "Likes", "Hates"])
    }
    static belongsTo = [ Person ]
}


class Person {
    String firstName
    String secondName
    .
    .
    .
    static hasMany= [ personToPerson:PersonToPerson, 
                      personToStore:PersonToStore ]
}

Редактировать: обновленный вопрос для ясности


Подумав над проблемой, думаю, у меня есть лучший способ задать вопрос (ы). В реализации PersonToPerson выше у меня есть отношение в виде простой строки. Я хочу, чтобы пользователь мог выбрать из списка уникальных отношений, которые определены в ограничениях, строковое значение для PersonToPerson. Так что это приводит к вопросам ...

  1. Следует ли объединить personToPerson и personToStore в один список типа Relationship? Или они должны оставаться независимыми списками, как показано?
  2. Каков механизм, позволяющий пользователю добавлять новые значения в ограничение отношения?

Ответы [ 2 ]

3 голосов
/ 19 июля 2010

1) Доменная модель

Сохраняйте свой код простым. Не создавайте общую модель данных. Это путь в ад. Когда вы personToPerson и personToStore разделяете, гораздо проще следовать вашему коду.

Фактически предлагаемое решение позволяет получить доступ к отношениям как к консолидированному, так и к независимому списку одновременно.

Для этой проблемы я бы использовал функцию наследования в GORM .

Ваши занятия будут выглядеть так:

class Person {
    String name
    static hasMany = [personToPerson:PersonToPerson,
                      personToProduct:PersonToProduct,
                      personToStore:PersonToStore]

    static mappedBy = [personToPerson:"from"]
}

class Product{
    String productName
}

class Relationship{
    String note
}

class Store{
    String storeName
}

class PersonToPerson extends Relationship{
    Person from
    Person to
    String relation

    static constraints = {
         relation(inList:["Friend to", "Enemy of", "Likes", "Hates"])
    }
    static belongsTo = [ from:Person ]
}

class PersonToProduct extends Relationship{
    Person person
    Product product
    String relation

    static constraints = {
         relation(inList:["likes", "dislikes"])
    }
    static belongsTo = [ person:Person ]
}

class PersonToStore extends Relationship{
    Person person
    Store store
    String relation

    static constraints = {
        relation(inList:["Stock person", "Owner", "Manager", "Patron"])
    }
    static belongsTo = [ person:Person ]
}

Схема БД для Person, Product и Store обычная. Но для реляционных доменов это выглядит так:

Отношения

Field      Type         Null Default 
id         bigint(20)   No   
version    bigint(20)   No   
note       varchar(255) No   
class      varchar(255) No   
person_id  bigint(20)   Yes  NULL  
product_id bigint(20)   Yes  NULL  
relation   varchar(8)   Yes  NULL  
from_id    bigint(20)   Yes  NULL  
to_id      bigint(20)   Yes  NULL  
store_id   bigint(20)   Yes  NULL   

Домен отношений позволяет получить доступ ко всем реляционным доменам через один домен.

2) Ограничение

Просто переключите inList на validator . Чем вы можете хранить ограничения в файле или БД. См. документацию или пример файла .

Пример, как хранить значения ограничений в БД. Сначала создайте объект домена.

class Constrain{
    String name
    String type
}

Чем выглядит класс домена:

class PersonToPerson extends Relationship{
    Person from
    Person to
    String relation

    static constraints = {
         relation(nullable:false, validator:{val, obj ->
             def list = Constrain.findAllByType('person').collect{it.name}
             return list.contains(val)
         })
    }
    static belongsTo = [ from:Person ]
}
0 голосов
/ 15 июля 2010

Выглядит хорошо. Возможно, вы захотите рассмотреть принадлежность в классе PersonToPerson.

Кроме того, у вас должно быть много Личных: [personToPersons: PersonToPerson .... <- удалить s </p>

...