2014-01-13 2 views
13

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

  • Любых изменений на расширенном экземпляре домена, должен быть сохранен (как вариант из него) для истории
  • только одна версии экземпляра может быть активный
  • Пользователь должен иметь возможность активировать версию экземпляра (текущий активный экземпляр должен быть отключен), который не создал им (4 глаза принцип)
  • вид дифф приятно иметь

Вмешательство в Grails из сценариев коробки должно быть как можно меньше. я идентифицировал до сих пор 3 разработки стратегий осуществления:

  1. Зеркала таблицы с одной и той же схемой, которая содержит версии (парную графа доменов/таблиц). Активированная версия будет скопирована в собственный домен и наоборот.
  2. Использование дискриминатора в классе домена. Некоторые новые колонки будут добавлены в домен (например, состояние [активен, notActive], lastUpdatedBy, lastUpdatedDate ...)
  3. (Де-) Сериализация экземпляров в специальной области с BLOB (например, domain.properties в формате JSON)

Любое из решений имеет свои плюсы и минусы. Каков наилучший подход к его внедрению? Возможно, есть более простой способ.

+5

Никогда не пробовал, но вы могли бы найти http://refaktor.blogspot.co.uk/2012/08/hibernate-envers-with-grails-210.html интересный? –

+3

@tim_yates, пожалуйста, разместите его как ответ, чтобы я мог его принять. В вашем предложении используется плагин спящего режима с именем Envers. Он реализует первую стратегию, описанную в моем вопросе. Он работает нормально. Единственным недостатком является то, что изменение db должно быть внутри транзакции, что не относится к контроллеру. – Waldemar

+0

Независимо от стратегий, это хорошая идея использовать динамические леса в Grails для их реализации. Для каждого домена вам нужны специальные функции, создайте пустой контроллер с scaffold = true. Затем установите шаблоны и измените их. Например. изменить действие списка, чтобы отфильтровать неактивные объекты. – Waldemar

ответ

2

Я разрабатываю систему в Grails, которая интенсивно использует концепцию версии (как вы говорили выше). Мой подход был вторым в вашем вопросе.

Я создал два поля: internalVersion e disabled. Каждый класс, который должен быть Versionable, должен реализовать интерфейс, называемый Versionable.

Я попробую объяснить здесь один из сценариев, в которых необходимо использовать функциональность версии (простите мой английский).

Система, использующая эту концепцию, представляет собой коммерческую систему, в которой есть класс под названием Quote.

Каждая цитата может содержать одну или несколько версий, где действительна только последняя версия. Каждая цитата и ее версии создаются на основе переговоров с конкретным клиентом. Таким образом, клиент запрашивает у нас Цитату, и если по какой-то причине ему не нравятся цены (например), мы можем создать новую версию с некоторой скидкой. Каждая цитата имеет уникальный код, следующий текущей версией, например: QT-000022/0 (первая версия), QT-000022/1 (вторая версия).

Чтобы создать новую версию, я использую метод, который клонирует текущий объект (используя вид полного и глубокого сохранения как). Я копирую все (свойства и коллекции) в новый объект.

Метод клонирования определяет, что класс реализует интерфейс Versionable и выполняет следующие функции:

oldQuote.disabled = true 
newQuote.internalVersion = oldQuote.internalVersion + 1 

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

Надеюсь, вы понимаете мой подход.

+0

Переписать метод clone - отличная идея. Если вы создадите индекс в столбцах, у него не будет проблем с производительностью. У вас все еще есть недостаток варианта 2.nd, что он не прозрачен для приложения. Каждый запрос должен знать хотя бы «отключенный» столбец. – Waldemar

Смежные вопросы