grails: sort by nested attributes - grails

Is it possible to sort by nested attributes using where queries?
I have 2 domain classes:
class Parent {
String name
Child child
}
and
class Child {
String name
static belongsTo = [parent: Parent]
}
This works:
Parent.where {}.list(sort: 'name')
and this doesn't:
Parent.where {}.list(sort: 'child.name')
I have an error:
could not resolve property: child.name of: Parent
I am using grails 2.3.x

See this: Grails - sort by the domain relation attribute (using createCriteria())
Solution 1:
def criteria = Child.createCriteria();
println criteria.list{
createAlias("parent","_parent")
order( "_parent.name")
}
Solution 2:
def criteria = Child.createCriteria();
println criteria.list{
parent {
order("name")
}
}
Solution 3:
class Child {
String name
static belongsTo = [parent: Parent]
public String getParentName(){
return parent.getName()
}
}
println Child.listOrderByParentName()
Hope it helps.

Related

Escaping association name in grails criteria to not conflict with containing class variable name

This is the simplified version of my grails domain class:
class Car {
int year
Model model
List<Car> findCarsBySomeCriteria(int modelId) {
BuildableCriteria c = createCriteria()
List<Car> carList = (List<Car>) c.list {
'in'("year", [1998, 1999])
model {
eq("id", modelId)
}
}
carList
}
}
Turns out that this criteria query fails as the model association mentioned in the query conflicts with the model property of the class.
Is there any way to escape the model in criteria query ?
Try createAlias, like
List<Car> carList = (List<Car>) c.list {
'in'("year", [1998, 1999])
createAlias('model', 'mdl')
eq("mdl.id", modelId)
}

How to get value in my show page in Grails

How to get the value as following codes with my show view page on Grails?
Person.groovy
package com
class Person {
String person
static constraints = {
person blank:false,nullable:true
}
static hasMany=[task:Task]
String toString(){return person}
static mapping={
}
}
Task.groovy
package com.moog
class Task {
String task
static constraints = {
task blank:false,nullable:true,unique:true
}
static belongsTo=[person:Person]
static hasMany=[tag:Tag]
String toString(){return task}
}
Tag.groovy
package com
class Tag {
String tag
static constraints = {
tag blank:false, nullable:true
}
static belongsTo=[task:Task]
String toString(){
return tag
}
}
First of all try a better wording for your collections
static hasMany=[tasks:Task] // in Person.groovy
static hasMany=[tags:Tag] // in Task.groovy
In your person show.gsp try something like
<g:each in=${person.tasks} var="task">
<p>${task}</p>
</g:each>
If you do not use scaffolding and write you own controller methods to create your entities than maybe this helps you further:
def task = new Task(task:"Clean room")
def person = Person.get(1)
person.addToTasks(task)
person.save()

Grails createCriteria on abstract domain

I am quite curious how one would use the criteria builder to access fields of an inherited class.
Let's assume we have the following class:
class A {
String fieldOne
String fieldTwo
static hasMany = [childs: AbstractChildClass]
}
and the abstract child class would look like this:
abstract class AbstractChildClass {
Integer valueOne
Integer valueTwo
A a
static mapping
tablePerHierarchy false
}
}
of course there are several extending classes such as:
class ExtendingClassOne extends AbstractChildClass {
DesiredObject desiredObject
static mapping = {
tablePerHierarchy false
}
}
let's also assume there is the class DesiredObject which looks like this:
class DesiredObject {
String infoA
String infoB
}
The question is how one would get the fields infoA and infoB by creating a criteria for class A. My approach so far is this:
A.createCriteria().list {
childs {
desiredObject {
ilike('infoA', '%something%')
}
}
}
This of course does not work because in the table ExtendingClassOne is only the id of the desiredObject and I have no clue how to join the object with the criteria builder to get its fields.
Thank you for reading.
Marco
don't expect 100% match between your domain model and the DB schema it's related to.
In your case the polymorphism would work only with tablePerHierarchy true for AbstractChildClass.
If you do want to stick with tablePerHierarchy false, you can define your class like:
class A {
static hasMany = [ childrenOne:ExtendingClassOne, childrenTwo:ExtendingClassTwo ]
}
thus your query would be as simple as:
A.withCriteria{
for( String c in [ 'childrenOne', 'childrenTwo' ] ){
"$c"{
desiredObject {
ilike('infoA', '%something%')
}
}
}
}

Grails criteria select when hasMany hasn't any elements

I have the classes:
class Course{
String name
static hasMany = [
studentGrades: StudentGrade
]
}
class StudentGrade{
String name
int grade
}
How can I make a criteria to get the courses without any student grade?
You could use the isEmpty criterion method:
def c = Course.createCriteria()
def results = c.list {
isEmpty("studentGrades")
}
See the docs for further informations.

Dependency Injection In Grails Domain Controllers

I'm trying to create a a custom constraint. I've put the logic in a service:
class RegExpManagerService {
boolean transactional = false
def messageSource
def lookupRegexp(regExpression,Locale locale) {
def pattern = messageSource.getMessage( regExpression,null,locale )
return pattern
}
def testRegexp(regExpression,text,Locale locale) {
return text ==~ lookupRegexp(regExpression,locale)
}
}
and tried to inject it in my domain controller:
class Tag extends IbidemBaseDomain {
def regExpManagerService
static hasMany=[itemTags:ItemTag]
static mapping = {
itemTags fetch:"join"
}
//Long id
Date dateCreated
Date lastUpdated
String tag
// Relation
Tagtype tagtype
// Relation
Customer customer
// Relation
Person updatedByPerson
// Relation
Person createdByPerson
static constraints = {
dateCreated(nullable: true)
lastUpdated(nullable: true)
tag(blank: false,validator: {val,obj ->
regExpManagerService.testRegexp(obj.tagtype.regexpression,val,local)
})
tagtype(nullable: true)
customer(nullable: true)
updatedByPerson(nullable: true)
createdByPerson(nullable: true)
}
String toString() {
return "${tag}"
}
}
When the constraint gets executed I get this error:
2009-08-24 18:50:53,562 [http-8080-1] ERROR errors.GrailsExceptionResolver - groovy.lang.MissingPropertyException: No such property: regExpManagerService for class: org.maflt.ibidem.Tag
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingPropertyException: No such property: regExpManagerService for class: org.maflt.ibidem.Tag
The constraints closure is static, so it can't see the instance field 'regExpManagerService'. But you have the object being validated so you can access it from that:
tag(blank: false,validator: {val,obj ->
obj.regExpManagerService.testRegexp(obj.tagtype.regexpression,val,local)
})

Resources