Tôi đang làm việc để xây dựng một động cơ createCriteria
. Cho đến nay, như vậy tốt:Xây dựng createCriteria trong Grails động và theo cách DRY?
obj
là đối tượng miền (s) Tôi muốn trở lại
rulesList
là danh sách các bản đồ mà giữ lĩnh vực này để được tìm kiếm trên, các nhà điều hành để sử dụng, và giá trị để tìm kiếm đối
def c = obj.createCriteria()
l = c.list (max: irows, offset: offset) {
switch(obj){ //constrain results to those relevant to the user
case Vehicle:
eq("garage", usersGarage)
break
case Garage:
users {
idEq(user.id)
}
break
}
rulesList.each { rule ->
switch(rule['op']){
case 'eq':
eq("${rule['field']}", rule['value'])
break
case 'ne':
ne("${rule['field']}", rule['value'])
break
case 'gt':
gt("${rule['field']}", rule['value'])
break;
case 'ge':
ge("${rule['field']}", rule['value'])
break
case 'lt':
lt("${rule['field']}", rule['value'])
break
case 'le':
le("${rule['field']}", rule['value'])
break
case 'bw':
ilike("${rule['field']}", "${rule['value']}%")
break
case 'bn':
not{ilike("${rule['field']}", "${rule['value']}%")}
break
case 'ew':
ilike("${rule['field']}", "%${rule['value']}")
break
case 'en':
not{ilike("${rule['field']}", "%${rule['value']}")}
break
case 'cn':
ilike("${rule['field']}", "%${rule['value']}%")
break
case 'nc':
not{ilike("${rule['field']}", "%${rule['value']}%")}
break
}
}
}
}
Mã trên hoạt động tốt và chỉ có một chút chi tiết với các câu lệnh chuyển đổi. Nhưng điều gì sẽ xảy ra nếu tôi muốn thêm chức năng để chọn BẤT K of quy tắc hoặc TẤT CẢ chúng? Tôi sẽ cần phải có điều kiện đặt các quy tắc trong một or{}
. Tôi không thể làm điều gì đó như
if(groupOp == 'or'){
or{
}
trước khi tôi đi qua các rulesList và sau đó
if(groupOp == 'or'){
}
}
sau đó. Tất cả những gì tôi có thể nghĩ là lặp lại mã cho từng điều kiện:
if(groupOp == 'or'){
or{
rulesList.each { rule ->
switch(rule['op']){
...
}
}
}
}
else{
rulesList.each { rule ->
switch(rule['op']){
...
}
}
Bây giờ mã trông khá cẩu thả và lặp đi lặp lại. Giả sử tôi muốn tìm kiếm trên thuộc tính của thuộc tính của đối tượng miền? (Ví dụ: Tôi muốn trả lại các phương tiện có lốp xe là một thương hiệu nhất định; xe.tires.brand hoặc các phương tiện có trình điều khiển phù hợp với tên; vehicle.driver.name). Tôi sẽ phải làm một cái gì đó như:
switch(rule['op']){
case 'eq':
switch(thePropertiesProperty){
case Garage:
garage{
eq("${rule['field']}", rule['value'])
}
break
case Driver:
driver{
eq("${rule['field']}", rule['value'])
}
break
}
break
case 'ne':
...
}
Giải pháp tuyệt vời, có vẻ như tôi vẫn chưa nhận ra và tận dụng toàn bộ sức mạnh của Groovy. Ngoài ra, đối với bất cứ ai quan tâm đến việc tìm hiểu thêm về createAlias (mà tôi không biết gì về trước đây) xem qua [ở đây] (http://adhockery.blogspot.com/2009/06/querying-by-association-redux.html) – Weezle
Cảm ơn ! createAlias đã giải quyết được vấn đề của tôi. Tôi không biết tại sao nó không được đề cập trên trang createCriteria của tài liệu Grails. – Ben