Grails: find domain class by name
Asked Answered
T

1

18

I want to allow users to traverse the domain classes and print out dumps of stuff. My frist problem: assuming the following works just fine:

//this works
class EasyStuffController{
  def quickStuff = {
    def findAThing = MyDomainClass.findByStuff(params.stuff)
    [foundThing:findAThing]
  }
}

What is the proper way to write what I am trying to say below:

//this doesn't
class EasyStuffController{ servletContext ->
  def quickStuff = {
    def classNameString = "MyDomainClass" //or params.whichOne something like that
    def domainHandle = grailsApplication.domainClasses.findByFullName(classNameString)
    //no such property findByFullName
    def findAThing = domainHandle.findByStuff(params.stuff)
    [foundThing:findAThing]
  }
}



//this also doesn't
class EasyStuffController{ servletContext ->
  def quickStuff = {
    def classNameString = "MyDomainClass" //or params.whichOne something like that
    def domainHandle 
    grailsApplication.domainClasses.each{
      if(it.fullName==classNameString)domainHandle=it
    }
    def findAThing = domainHandle.findByStuff(params.stuff)
    //No signature of method: org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass.list() is applicable
    [foundThing:findAThing]
  }
}

Those lines above don't work at all. I am trying to give users the ability to choose any domain class and get back the thing with "stuff." Assumption: all domain classes have a Stuff field of the same type.

Thelma answered 14/6, 2011 at 1:25 Comment(0)
E
45

If you know the full package, you can use this:

String className = "com.foo.bar.MyDomainClass"
Class clazz = grailsApplication.getDomainClass(className).clazz
def findAThing = clazz.findByStuff(params.stuff)

That will also work if you don't use packages.

If you use packages but users will only be providing the class name without the package, and names are unique across all packages, then you can use this:

String className = "MyDomainClass"
Class clazz = grailsApplication.domainClasses.find { it.clazz.simpleName == className }.clazz
def findAThing = clazz.findByStuff(params.stuff)
Excrescent answered 14/6, 2011 at 1:54 Comment(5)
I get the error(using the second method and className="Account"): Cannot cast object 'Artefact > Account' with class 'org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass' to class 'java.lang.Class' due to: java.lang.ClassNotFoundException: Artefact > AccountThelma
Sorry about that, I edited the answer to get the Java class from the DomainClass.Excrescent
@burt: I believe, you missed a .clazz in the second line of your first example (just like you added to the second block). Unfortunately the funny naming prevented my edit to be approved :-)Moria
Is this approach still applicable in versions later than 2.3.x?Quirinus
Looks like with grails 3, the getArtefact method doesnt work if you dont specify the class name with packageChiropteran

© 2022 - 2024 — McMap. All rights reserved.