How can I override the "map" constructor in a Grails domain class?

I need to do some initialization when creating new instances of my domain class.

class ActivationToken { String foo String bar } 

When I do this, I want the bar to be initialized with code inside the ActivationToken:

 def tok = new ActivationToken(foo:'a') 

I don’t see how to β€œoverride” the constructor for this to happen. I know that in this case I could just add a regular constructor, but this is just a simple example.

+6
source share
2 answers

The map constructor comes from Groovy - not Grails in this case. I did some experiments, and this is what I came up with:

 class Foo { String name = "bob" int num = 0 public Foo() { this([:]) } public Foo(Map map) { map?.each { k, v -> this[k] = v } name = name.toUpperCase() } public String toString() { "$name=$num" } } assert 'BOB=0' == new Foo().toString() assert 'JOE=32' == new Foo(name:"joe", num: 32).toString() 

Basically, you will have to manually override the constructors if you need to process the property after building.

Alternatively, you can redefine individual setters, which are generally cleaner and safer:

 class Foo { String name = "bob" int num = 0 public void setName(n) { name = n.toUpperCase() } public String toString() { "$name=$num" } } assert 'bob=0' == new Foo().toString() assert 'JOE=32' == new Foo(name:"joe", num: 32).toString() 

Please note that the default value is not processed, but in most cases this should be fine.

+17
source

The above solution is also useful for cases when initializing an object from parameters in a web request, for example, when you want to ignore extraneous values, catching missing property exceptions.

 public Foo(Map map) { try { map?.each { k, v -> this[k] = v } } catch(Exception e){ } } 
0
source

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


All Articles