Устранение детско-родительской ассоциации в GORM - PullRequest
3 голосов
/ 10 ноября 2011

Рассмотрим следующие классы доменов

class Business{
    static hasMany = [contacts:ContactPerson]
}

class ContactPerson{
}

С учетом следующих классов доменов, скажем, мы используем следующие примеры:

Алиса является контактным лицом ACME. Боб и Кэрол являются контактными лицами Calamity Corp.

Скажем, я хотел удалить Боба из таблицы ContactPerson. Таким образом:

bob.delete(flush:true)

Но код приведет к тому, что сервер будет жаловаться на ограничения:

ERROR: update or delete on table "contact_person" violates foreign key constraint
    "fk4a69c6b329ef2fe1" on table "business_contact_person"
Detail: Key (id)=(174) is still referenced from table "business_contact_person".

В этом контексте выдается исключение, потому что Боб все еще связан с Calamity Corp.

Как удалить Боба из таблицы ContactPerson? Я хотел полностью удалить Боба из базы данных. Я не хочу добавлять принадлежность, так как я не хочу каскадно удалять дочерние элементы Business (то есть, если я удаляю Acme Corp из базы данных, я все же хочу, чтобы Алиса была в системе).

Я видел примеры отсоединения родителя от ребенка , но не наоборот.

Ответы [ 2 ]

4 голосов
/ 11 ноября 2011

Хорошо.Поэтому, немного покопавшись, я наконец-то получил коды, которые хотел.Сообщение Джона Реллиса о Совет по отношениям: Grails One-To-Many было особенно полезным.В этой статье он упоминает, как выполнять запросы от детей к родителям (это именно то, что я ищу).

Возвращаясь к вопросу, я хотел удалить Боба из таблицы ContactPerson, но с учетом взаимосвязи междуБизнес и ContactPerson просто вызывая bob.delete () просто не будет делать.Что мне нужно, это искать все предприятия, связанные с Бобом, и удалить ассоциацию.Таким образом, код ниже:

def bob = ContactPerson.get(params.id)

def criteria = Business.createCriteria()

def businesses = criteria.listDistinct{
    createAlias("contactPersons","c")
    eq("c.id", bob.id)
}

businesses.each{business->
    business.removeFromContactPersons(bob)
    business.save(flush:true)
}

bob.delete(flush:true)

Я также добавил новое отображение в модель бизнес-домена:

static mapping = {
    children cascade:"all-delete-orphan"
}
4 голосов
/ 10 ноября 2011

Я полагаю, просто добавив belongsTo, каскад должен работать как положено ...

class Business{
  static hasMany = [ contacts:ContactPerson ]
}

class ContactPerson{
  static belongsTo = [ business: Business ]
}
...