Grails - Предотвращение рекурсивных отношений один ко многим - PullRequest
1 голос
/ 27 октября 2011

У меня есть следующий класс домена в Grails:

class TreeNode {
    String name
    String description

    static hasMany = [childNodes: TreeNode]
}

Какой самый идиоматичный способ Grails обеспечить, чтобы экземпляр TreeNode не мог быть дочерним? Могу ли я сделать это как ограничение в классе домена или мне следует написать собственный код в действии «Сохранить» в TreeNodeController?

Ответы [ 2 ]

1 голос
/ 28 октября 2011

Ответ зависит от того, насколько глубоко вы хотите проверить детей.Если вы беспокоитесь только о непосредственных потомках, то код из @Tiggerizzy должен работать просто отлично.

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

  1. Если изменятся другие свойства в узле, но не структура дерева, вы можете пропустить проверку дочерних элементов и сэкономить себе дополнительное время обработки при проверке.
  2. Если вы проверяете из-под или в корне дерева, тогда проверка всех дочерних дочерних элементов будет более длительным процессом для большого дерева, требующего большой работы с базой данных.Выполняя эту работу в классе Service, вы получаете транзакционный характер службы, который будет откатывать любые изменения базы данных на необработанном Exception, например, в ситуации оптимистической блокировки с другим потоком.
1 голос
/ 27 октября 2011

Сделайте это как пользовательское ограничение.

static constraints = {
  childNodes(validator: {value, obj, errors->
      if(value.contains(obj) {
        errors.rejectValue('childNodes', 'Cannot contain self')
      }
  }
}
...