Load children dynamically using Grails Fixture plugin - grails

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!

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/

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
}
}

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

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 }

Get domain class field names

I would like to get the field names of a class and maybe store it in a list. Can anyone help? Thanks.
You can try this to get field names of domain class.
YourClass.declaredFields.each {
if (!it.synthetic) {
println it.name
}
}
You can use gormPersistentEntity for any domain object, this works with Grails 2.4.4 at least:
def names = Person.gormPersistentEntity.persistentPropertyNames
//returns ['firstName', 'lastName'...]
you can also get natural name using GrailsNameUtils like so:
def naturalNames = Person.gormPersistentEntity.persistentPropertyNames.collect {
grails.util.GrailsNameUtils.getNaturalName(it)
}
//returns ['First Name', 'Last Name'...]
def capitilizedNames = Person.gormPersistentEntity.persistentProperties.collect{
it.capitilizedName
}
//returns ['FirstName', 'LastName'...]
Just found it out, this one works:
def names = grailsApplication.getDomainClass('com.foo.Person').persistentProperties.collect { it.name }
You can iterate over the fields of a class like this.
YourClass.fields.each { println it.name }
If you need to put them into a list you could use collect() or populate it within the each.
http://groovy.codehaus.org/JN3535-Reflection

How to use the withCriteria results in a new withCriteria query in Grails?

Consider the first query:
def books = Book.withCriteria {
eq("category", "fiction")
}
How can I use the result of this query in the next query to get all the authors who wrote these books?
I tried:
def authors = Author.withCriteria {
'in'("books", books)
}
but this is not working. What can I do to fix it?
Can't you just query the association directly?
def authors = Author.withCriteria {
books {
eq("category", "fiction")
}
}

Resources