How can I get a set of field values in groovy? - grails

class Book {
String title
}
def book = new Book(title: 'title1')
def book = new Book(title: 'title2')
def book = new Book(title: 'title3')
How can I get the set of titles? Something like titleSet = ['title1', 'title2', 'title3']
I thought maybe something like def titleSet = Book.findTitles(); would work but I can't find anything like that.
I know I could do:
def books = Book.list()
def titleSet
for(def book : books)
titleSet.add(book.title)
But I'm looking for a groovier way.

This goes through all the books for their title and creates a Set instead of a List.
Book.all.title as Set
UPDATE
The above will fetch all Book instances which might be heavy if you only need title. You can also try using criteria or HQL to get only list of titles.
def titleSet = Book.createCriteria().listDistinct {
projections {
property('title')
}
}

Try
Set titleSet = books*.title
Or
Set titleSet = books.collect { it.title }

Related

grails find arraylist string based on corresponding string

I have a method:
def nameToCode(nameStr){
def ret = resortService.getResort("all")
//this gets like 180 objects with various properties like name, code, etc.
def resorts = [name: ret.prName, code: ret.prProductIndex]
def code = resorts.findByName(nameStr) //this doesn't work
println(code)
return code
}
I'm trying to call this method and send it a name. It's then supposed to go find the name in the map, if it finds it it's supposed to return the name's code. This is supposed to be simple but I've been searching everywhere and can't figure out how to do this. I'll appreciate any help. Thanks
you are using a gorm method on a standard map:
Instead of :
def resorts = [name: ret.prName, code: ret.prProductIndex]
def code = resorts.findByName(nameStr) //this doesn't work
Try:
def resorts = [name: ret.prName, code: ret.prProductIndex]
def code = resorts.findAll{name==nameStr}

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/

Prevent criteria filter inside conjunctive statement

An example of what I'm trying to do is:
def authorName = "John Smith"
def books = Book.createCriteria().list() {
eq('genre', 'fiction')
eq('publishDate', '2007')
if(authorName != null){
Author author = Author.findWhere(name: authorName)
if( author == null ) //what do I do here?
else { eq('authorId', author.id }
}
}
If there is no author for the given id, then the author doesn't exist (assuming it wasn't removed) and thus there are no books written by the author. The evaluation should stop there and not return any results. What can I use to accomplish this?
I am not really 100% what you are trying to do. If you only want to execute Book query if the author exists, you could so something like this...
def authorName = "John Smith"
Author author = Author.findWhere(name: authorName)
def books
if(author) {
books = Book.withCriteria {
eq('genre', 'fiction')
eq('publishDate', '2007')
// I can't tell if this is the right thing because
// I don't know what your model looks like, but I will
// assume this part is valid because it is what you had
// in your example.
eq 'authorId', author.id
}
}
Depending on what your model looks like, you could also just make the authorName part of the criteria so now you don't have to execute 2 queries...
def authorName = "John Smith"
def books = Book.withCriteria {
eq('genre', 'fiction')
eq('publishDate', '2007')
// this assumes that Book has a property named
// "author" which points to the Author
author {
eq 'name', authorName
}
}

Load children dynamically using Grails Fixture plugin

I'm trying to load data in a Grails application using the Fixture plugin.
class Author {
String name
}
class Book {
String title
hasMany = [authors:Author]
}
I load Author in a separate file and include it in the Book one.
//author fixture
fixture {
author1(Author) {
name = 'Ken Follett'
}
author2(Author) {
name = 'Martin Fowler'
}
}
//book fixture
fixture {
include 'author'
"book"(Book) {
title = 'Your favorite book'
authors = [author1, author2]
}
}
This all works fine. What I can't do, is to replace [author1, author2] so I can dynamically (and randomly) assign authors. Something like:
def dynamicallyBuiltAuthorList = "author1, author2, author100"
authors = ["${dynamicallyBuiltAuthorList}"]
Pretty much everything I tried so far gave me a no matching editors or conversion strategy found error.
Thanks in advance Grails gurus!
Based on your answer below (and the previous edit to this answer), this is probably a better way:
def dynamicallyBuiltAuthorList = [ 'author1', 'author2', 'author100' ].collect {
ref( "$it" )
}
authors = dynamicallyBuiltAuthorList
In the end the answer is simply:
def authorList = []
def dynamicallyBuiltAuthorList = [ 'author1', 'author2', 'author100' ].collect {
authorList.add(ref("$it"))
}
authors = authorList
Thanks to Tim for the help!

Store sql.eachRow() of groovy sql to a List

do you know how to store the result from
sql.eachRow()
of groovy sql to a list? for example def personList = [] ?
example:
sql.eachRow('select lastname from users where id='active')
What I want is to store the result ie. lastnames to a list ie def personlist = [];
I know I can easily do this by namedQuery and I've already done it. But their is some underlying reason about this. Thanks in advance.
def reqdColName = "lastname"
def query = "select $reqdColName from users where id='active'"
Straight option would be to use the rows() method.
def list= Sql.rows(query) //returns groovyrowresult as list
Another option is you could use the executeQuery instead, to get hold of the resultset of the query and thereby get an array/list on it.
def array = Sql.executeQuery(query).getArray(reqdColName)
//If you need as a list
def personList = Arrays.asList(array)
I know that the question has been asked a long time ago, but still, I feel the answer may be of help for someone out there.
def personlist = []
sql = Sql.newInstance(url, username, password, driver)
query = "select $reqdColName from users where id='active'"
sql.eachRow(query)
{
row-> personlist << row.toString()
}
sql.close()
personlist.each{println it} // you can also return the list
def personList = sql.rows("select lastname from users where id='active'")*.lastname

Resources