Фильтрация по нескольким ассоциациям и необязательные предложения where - PullRequest
1 голос
/ 23 марта 2012

У меня есть несколько классов доменов, с некоторыми простыми ассоциациями между ними, как показано ниже:

class Business {
  String name
  City city
  Industry industry
}

class City {
  String name
}

class Industry {
  String name
}

В моем приложении я хотел бы иметь «фильтр», где список всех предприятий можетбыть отфильтрованы по городу и промышленности.Я могу получить идентификаторы города и промышленности от фильтра обратно к контроллеру Business, однако, когда я добираюсь до контроллера, чтобы выполнить фильтрацию, у меня есть этот код:

...
def industry = Industry.get(params.int('industryid'))
def city = City.get(params.int('cityid'))

def businessList = Business.findAllByIndustryAndCity(industry, city)
...

Этот код работает, когдаполя City и Industry имеют значения.Тем не менее, иногда пользователь может захотеть просто фильтровать по городу или отрасли, а не оба.В этом случае фильтр завершается ошибкой, так как когда любое из значений равно нулю, результаты не возвращаются.Как я могу указать, что если какое-либо из значений ассоциации равно "null", то запрос "find" должен полностью удалить это ограничение?т. е. соответствует «all» для этого поля

Обратите внимание, что я понимаю, что было бы легко поместить оператор if, проверяющий, равны ли значения значения null, и затем выполнить другой оператор «find» на основе этого.Однако, хотя это будет работать с двумя значениями, я не думаю, что оно будет хорошо масштабироваться, поскольку добавляются более фильтруемые значения.

1 Ответ

3 голосов
/ 23 марта 2012

Вы можете построить критерии.

def c = Business.createCriteria()
def results = c.list{
    and {
        if (industry) {
            eq("industry", industry)
        }
        if (city) {
            eq("city", city)
        }
    }
}

Проверьте ссылку здесь в документах Grails.

Однако ваш код требует N + 1 запросов для N параметров.Может быть, вы можете сократить его до одного запроса, используя критерий идеи?Если ваша сущность Business хранит внешние ключи как для Industry, так и для City, этот должен сработать:

def c = Business.createCriteria()
def results = c.list{
    and {
        if (params.industryid) {
            eq("industry_id", params.industryId as Long)
        }
        if (params.cityid) {
            eq("city_id", params.cityid as Long)
        }
    }
}

Оба примера не проверены, но вы должны понять.

...