Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails: Problem with nested associations in criteria builder

I have a frustrating problem with the criteria builder. I have an application in which one user has one calendar, and a calendar has many entries. Seems straightforward enough, but when I try to get the calendar entries for a given user, I can't access the user property (MissingMethodException). Here's the code:

def getEntries(User user) {
  def entries = [ClassName].createCriteria().list() {
    calendar {
      user {
        eq("id", user.id)
      }
    }
  }
}

I have even tried the following variation:

def getEntries(User user) {
  def entries = [ClassName].createCriteria().list() {
    calendar {
      eq("user", user)
    }
  }
}

That did not raise an exception, but didn't work either.

Here's the relevant parts of the domain classes:

class Calendar {
    static belongsTo = [user: User]
    static hasMany = [entries: Entries]

    ...
}

class User {
    Calendar calendar

    ...
}

class Entry {
    static belongsTo = [calendar: Calendar]

    ...
}

When Googling I came across a similar problem noted in early 2008: http://jira.codehaus.org/browse/GRAILS-1412

But according to that link this issue should have been solved long ago.

What am I doing wrong?

like image 645
Mr.B Avatar asked Dec 09 '22 17:12

Mr.B


2 Answers

I finally found the error!! The error wasn't at all related to criteria builder. The problem in this case was that I had user variable in the scope, so when I tried to enter the user relation by

calendar {
  user {
    eq("id", user.id)
  }
}

Grails thought that I wanted to call the user object/variable with a closure. I can once again use criteria builders freely :-)

Thanks for all your help and suggestions guys!

like image 128
Mr.B Avatar answered Dec 29 '22 12:12

Mr.B


If you have such scope errors like the poster of the question, you always can do the following. Lets say you have a user variable in your scope, then use

def user = User.get(...)
...
calendar {
  'user' {
    eq("id", user.id)
  }
}

instead of

def user = User.get(...)
...
calendar {
  user {
    eq("id", user.id)
  }
}
like image 27
codewandler Avatar answered Dec 29 '22 10:12

codewandler