GORM findAll doesn't work - grails

A have class Product:
class Product {
static hasMany = [attributeValues: ProductAttributeValue]
String productId
String manufacturer
BigDecimal price
static constraints = {
productId unique: true, blank: false
manufacturer blank: false
price min: BigDecimal.ZERO
}
}
I want to find all products, which productId contains substring 'filter'.
I wrote next code:
Product.findAll {it.productId.contains(filter)}
But it doesn't work. Why?

this should't work at all!
you have 2 options here:
1) you use propper GORM techniques like criteria query or HQL, the would look like:
Product.findAllByProductIdIlike( "%${filter}%" ) // dyn-finders
Product.withCriteria{ ilike 'productId', "%${filter}%" } // criteria
Product.findAll{ ilike 'productId', "%${filter}%" } // criteria
Product.findAll( "from Product where productId like '%?%'", [ filter ] ) // hql`
2) or use filtering on the whole dataset in grails app's memory (instead of the db) - NOT recommended:
Product.list().findAll{ it.productId.contains(filter) }

You can use regex,
Try this :
def yourProductIsWithFilter = '123filter456'
def matchingPattern = 'filter'
//def patternToMatch = /\b${matchingPattern}/\b
//def patternToMatch = /[A-Z_0-9${matchingPattern}/]
def patternToMatch = ~/.${matchingPattern}/
Product.findAll{it.productId =~ patternToMatch }
Note: I haven't tested the code.
Hope it gives you a heads up.
Regards

Related

How to compare collection item using createCriteria?

Registration domain has a collection of discounts.
static hasMany = [ discounts: Discount]
I want to extract all Registrations that have a particular discount applied.
In the following code i want to get all registrations whose collection has the discount of id disid. How can i achieve that? I appreciate any help!
def disid = Discount.get(1).id
def regs = Registration.createCriteria().list(){
eq('compositeEvent', cod.compositeEvent)
}
Try this:
def disid = Discount.get(1).id
def regs = Registration.withCriteria() {
discounts {
eq 'id', disid
}
}
See http://emmanuelrosa.com/articles/gorm-for-sqladdicts-where-clause/

Grails GORM : SELECT AS

I'm trying to get all the Users that are born today with GORM but I'm failing to write this query in Grails:
SELECT
DAY(dateOfBirth) AS 'day',
MONTH(dateOfBirth) AS 'month'
FROM Users
WHERE day = '...' AND month = '...';
... will be replaced with today's values.
Minimal User Domain class
class User {
Date dateOfBirth
...
}
Minimal UserService class
#Transactional
class UserService {
def getTodayBirthdays() {
def bornTodayQuery = User.where{
/* I'm thinking here I must
* select the DAY and MONTH from the DB
* and compare it with the today ones.
*/
}
User usersBornToday = bornTodayQuery.findAll()
usersBornToday
}
}
Any ideas how can I do an alias (SELECT field AS alias) with GORM?
I'm using:
Grails 2.4.4
Thanks!
You could use a where query in your service:
#Transactional(readOnly = true)
def listBirthday(int _month, int _day) {
// Calendar.JANUARY equals to zero!
def m = _month + 1
// Run a where query on the users
User.where {
month(dateOfBirth) == m && day(dateOfBirth) == _day
}
}
#Transactional(readOnly = true)
def listBirthdayToday() {
def cal = Calendar.getInstance()
listBirthday(cal.get(cal.MONTH), cal.get(cal.DAY_OF_MONTH))
}
In addition to month and day there are some other functions, here is the documentation (look for "Other Functions")
Any ideas how can I do an alias (SELECT field AS alias) with GORM?
(SELECT field AS _alias)
Putting an underscore (_) as prefix to alias worked for me with grails-2.5.6
I have not found it in documentation but using trail and error method.

Grails CRUD list order by a field

I have a domain class Project as below
class Project {
String projectName
String projectCode
String techLead
String projectManager
Date deliveryDate
String currentPhase
Integer priority
}
I have controller as below
class ProjectController {
def scaffold = Project
def index = {
redirect(action:list,params:params)
}
def list = {
// displays only 10 records per page
if (!params.max) params.max = 10
[ projectList: Project.list( params ) ]
}
}
I would like to display the list of projects in the sorting order or priority. How can I implement that ?
change your list action to the below
def list = {
// displays only 10 records per page
if (!params.max) {
params.max = 10
}
params.sort = "priority"
params.order = "asc" // change to "desc" to sort in the opposite direction
[projectList: Project.list(params)]
}
A much shorter and more idiomatic way of doing this would be to use the dynamic methods on list that provide ordering:
def list = {
[projectList: Project.listOrderByPriority(max: params.max ?: 10)]
}

How to filter Groovy/Grails closure from web app

I have a web app that makes a call to a grails app for its db calls. The db is filled with products that are returned through groovy calls. An example object that I would get from the db is as follows:
class Product{
Boolean is_blue;
Boolean is_round;
Boolean is_alive;
Boolean is_active;
String type;
String name;
}
I want to make a call to the grails app to filter on these boolean values but I am not sure how to do it via a closure, this what my closure currently looks like.
def productXML =
Product.findAll("from Product as p where p.is_active = 1 and p.type = :type
ORDER BY p.${params.sort} ${params.order}",
[type: type], [max: params.max, offset: params.offset])
What I'm most confused on is how I can pass these parameters to the closure. Any help would be greatly appreciated. Thanks.
Something like
def productXML =
Product.findAll("from Product as p where p.is_active is :active \
and p.type = :type \
ORDER BY p.${params.sort} ${params.order}",
[type: type, active: true],
[max: params.max, offset: params.offset])
OR
def productXML = Product.findAll(params){
type == type && is_active == active
}
is what you are looking for? Refer findAll for details.
Always use substitution variables
To make parameters optional, use this trick (using type as an example):
def productXML = Product.findAll("from Product as p where p.is_active is :active
and (p.type = :type or :type == null)
ORDER BY p.:sort :order",
[type: type, active: true, sort:params.sort, order:params.order], [max: params.max, offset: params.offset])
I ended up making a query builder where if in in the query string it had is_blue=1, I would add that to the query.
if(params.is_blue){
query +=" and p.is_blue = ${params.is_blue}"
}

how to grails find withCriteria or condition

String query='test'
def user = User.withCriteria {
ilike('firstName', '%'+query+'%')
or {ilike('lastName', '%'+query+'%')}
or {ilike('email', '%'+query+'%')}
}
above is the sample code i need to find those object if any one of three of these field( firstName lastName email ) contains query string
thnks
Try joining the conditions inside one or
or {
ilike('firstName', '%'+query+'%'),
ilike('lastName', '%'+query+'%'),
ilike('email', '%'+query+'%')
}
You can also turn on SQL debugging to see how your queries get built.
You can do in this way
String query='test'
def crit = User.createCriteria()
def user = User.list{
or{
ilike('firstName', '%'+query+'%')
ilike('lastName', '%'+query+'%')
ilike('email', '%'+query+'%')
}
maxResults(1000)
order("firstName")
}

Resources