Grails: найти класс домена по имени

Я хочу разрешить пользователям просматривать классы предметной области и распечатывать дампы. Моя первая проблема: предполагая, что следующее работает просто отлично:

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

Как правильно написать то, что я пытаюсь сказать ниже:

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

Эти строки выше вообще не работают. Я пытаюсь дать пользователям возможность выбирать любой класс домена и возвращать вещь с «вещами». Предположение: все доменные классы имеют поле Stuff одного типа.


person Mikey    schedule 14.06.2011    source источник


Ответы (1)


Если вы знаете полный пакет, вы можете использовать это:

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

Это также будет работать, если вы не используете пакеты.

Если вы используете пакеты, но пользователи будут указывать только имя класса без пакета, а имена уникальны для всех пакетов, вы можете использовать это:

String className = "MyDomainClass"
Class clazz = grailsApplication.domainClasses.find { it.clazz.simpleName == className }.clazz
def findAThing = clazz.findByStuff(params.stuff)
person Burt Beckwith    schedule 14.06.2011
comment
Я получаю сообщение об ошибке (используя второй метод и className = Account): Невозможно преобразовать объект «Artefact › Account» с классом «org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass» в класс «java.lang.Class» из-за: java.lang.ClassNotFoundException: Артефакт › Учетная запись - person Mikey; 15.06.2011
comment
Извините за это, я отредактировал ответ, чтобы получить класс Java из DomainClass. - person Burt Beckwith; 15.06.2011
comment
@burt: я полагаю, вы пропустили .clazz во второй строке вашего первого примера (точно так же, как вы добавили во второй блок). К сожалению, забавное название предотвратил одобрение моего редактирования :-) - person martin; 24.08.2012
comment
Применим ли этот подход в более поздних версиях, чем 2.3.x? - person John Giotta; 20.09.2014
comment
Похоже, что с Grails 3 метод getArtefact не работает, если вы не укажете имя класса с пакетом - person Sudhir N; 11.03.2017