Фильтрация запросов критериев GORM, где идентификатор в списке

Я пытаюсь добавить пункт к существующим критериям GORM, чтобы выполнить дополнительную фильтрацию.

В моем домене есть различные объекты, принадлежащие Organisation. Например, Product. Организации также могут владеть другими организациями. Я хочу, чтобы только User, принадлежащие определенному Organisation, могли видеть объекты домена, принадлежащие этому Organisation или любому из их Organisation дочерних Organisation.

В моем приложении есть несколько мест, где мне нужно запросить объекты домена, принадлежащие Organisations. Я хочу создать экземпляр DetachedCriteria, который я могу повторно использовать в приложении везде, где мне нужно отфильтровать объекты, которые User не должен видеть.

Я немного денормализовал свою модель, чтобы упростить задачу. Когда вставляется новый Organisation, он рекурсивно добавляет себя в коллекцию hierarchyOrganisations каждого из Organisations над ним.

class Organisation {
    ...
    static hasMany = [hierarchyOrganisations: Organisation]
    ...
}

Одно из мест, где я хочу применить фильтрацию организации DetachedCriteria, находится в методе list контроллера скаффолдинга Grails, поэтому мне нужно иметь возможность разбить окончательный набор результатов на страницы.

Используя в качестве примера метод списка контроллера Product, я сейчас делаю что-то вроде этого:

def hierarchyCriteria = new DetachedCriteria(Organisation).build {
    eq('id', currentUserOrganisation.id)
}

def productInstanceList = Product.createCriteria().list {
    inList('parentOrganisation.id', hierarchyCriteria.list().each { organisation -> 
        organisation.hierarchyOrganisations.collect { it.id }
    })
}

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

Если бы я использовал SQL, я мог бы использовать соединение или внутренний выбор, но я не могу правильно понять синтаксис, переводя это в критерии GORM dsl.


person rcgeorge23    schedule 22.05.2013    source источник


Ответы (2)


def organisationInstanceList = Organisation.createCriteria().list {
    idEq(currentUserOrganisation.id)
    hierarchyOrganisations{
      //Eagerly fetch all children for the parent org
    }
}

def children = organisationInstanceList?.first().hierarchyOrganisations

Возможно, я слишком упрощаю, но приведенное выше должно дать вам parent организации и соответствующие children организации. Что еще тебе нужно?

Добавление к опции @Sergio:

Денормализация может быть ненужной. Модель данных может использоваться как

class Organisation {
    Organization parent
}

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

Чтобы получить все дочерние элементы (разбитые на страницы) от родителя, используйте

def children = Organization.findAllByParent(currentUserOrganisation, [max: params.max, offset: params.offset])
person dmahapatro    schedule 22.05.2013
comment
Может быть, он хочет детей и должен их разбивать на страницы? - person ; 22.05.2013
comment
Добавил этот вариант (на самом деле более простой), а также @SérgioMichels. :) - person dmahapatro; 22.05.2013
comment
Спасибо за ваши ответы, ребята. Перечитывая свой вопрос, я понял, что на самом деле не очень четко изложил свое требование - мне нужно запрашивать не только иерархические организации, мне нужно иметь возможность запрашивать любой объект в моем домене и применять «фильтр организации». ', чтобы убедиться, что каждый объект домена, возвращаемый моим запросом, принадлежит одной из организаций в моей иерархии или организациях. Я немного переформулировал вопрос и использовал другой объект из моего домена в качестве примера того, к чему мне нужно применить фильтр. - person rcgeorge23; 23.05.2013

Я только что использовал SQL для увеличения критериев.

Добавив блок sqlRestriction к моему критерию dsl, я смог добавить подзапрос, чтобы применить необходимую фильтрацию.

Мне все еще было бы интересно узнать, возможно ли это, используя только критерии hibernate grails dsl.

person rcgeorge23    schedule 29.05.2013