Cannot use grails g.link in domain class

I have a static method in a domain class that returns a url. I need to create this url dynamically, but g.link is not working.

static Map options() { // ... def url = g.link( controller: "Foo", action: "bar" ) // ... } 

I get the following errors:

 Apparent variable 'g' was found in a static scope but doesn't refer to a local variable, static field or class. Possible causes: You attempted to reference a variable in the binding or an instance variable from a static context. You misspelled a classname or statically imported field. Please check the spelling. You attempted to use a method 'g' but left out brackets in a place not allowed by the grammar. @ line 17, column 19. def url = g.link( controller: "Foo", action: "bar" ) ^ 1 error 

Obviously my problem is that I am trying to access g from a static context, so how do I get around this?

+6
source share
2 answers

The g object is a taglib that is not available inside the domain class, as if it were in the controller. You can get it through grailsApplication , as shown below: How to call Taglib as a function in a domain class

The best way to do this in Grails 2+ is through the grailsLinkGenerator service, for example:

 def grailsLinkGenerator def someMethod() { def url = grailsLinkGenerator.link(controller: 'foo', action: 'bar') } 

In both cases, you will need to do extra work to get grailsApplication / grailsLinkGenerator from a static context. The best way is probably to capture this domainClass property of your domain class:

 def grailsApplication = new MyDomain().domainClass.grailsApplication def grailsLinkGenerator = new MyDomain().domainClass.grailsApplication.mainContext.grailsLinkGenerator 
+9
source

If you are using Grails 2.x, you can use the LinkGenerator API. Here is an example, I am reusing a domain class that I tested earlier, so Ignore non-URL functions.

 class Parent { String pName static hasMany = [children:Child] static constraints = { } static transients = ['grailsLinkGenerator'] static Map options() { def linkGen = ContextUtil.getLinkGenerator(); return ['url':linkGen.link(controller: 'test', action: 'index')] } } 

Utility class with static method

 @Singleton class ContextUtil implements ApplicationContextAware { private ApplicationContext context void setApplicationContext(ApplicationContext context) { this.context = context } static LinkGenerator getLinkGenerator() { getInstance().context.getBean("grailsLinkGenerator") } } 

Bean Def for the new Bean utility

 beans = { contextUtil(ContextUtil) { bean -> bean.factoryMethod = 'getInstance' } } 

If you need a base URL, add absolute:true to the link invocation.

+5
source

Source: https://habr.com/ru/post/918967/


All Articles