Grails - How to access configuration values in domain classes?

368 Views Asked by At

Although this or similar questions have been asked before for much older versions of grails, I wonder what would be the best approach to access a configuration value from application.yml in a grails domain class with modern grails 4.0.3.

So, let's say we have a voucher.groovy like

class Voucher implements HibernateEntity<Voucher> {
  ...

  Date reservedAt

  static transients = ['validUntil']

  Date getValidUntil() {
    Integer expirationTime = // TODO: fill in the configuration value

    DateTime expirationDateTime = new DateTime(this.reservedAt)
        .plusDays(expirationTime)
        .withHourOfDay(23)
        .withMinuteOfHour(59)
        .withSecondOfMinute(59)
        .withMillisOfSecond(999)
    return expirationDateTime.toDate()
  }

}

and a configuration value named voucher.expirationTime in our application.yml like

...
voucher.expirationTime: 10
...

How could I access the config value in my getValidUntil() method?

EDIT

As @JeffScottBrown mentioned in his comment, you shouldn't access config values in your domain class. So I ended up with his suggested apporach using a custom gsp tag. (See the answer below)

1

There are 1 best solutions below

0
On BEST ANSWER

How to access configuration values in domain classes? You shouldn't!

In my case I needed to display a derived value as a combination of a domain attribute and a configuration value reservedAt + expirationTime. Thanks to Jeff Scott Brown's comment, I managed to create a custom gsp tag for my purpose:

class VoucherTagLib {
  static returnObjectForTags = ['validUntil']
  static namespace = "voucher"

  @Value('${voucher.expirationTime}')
  Integer expirationTime

  GrailsTagDateHelper grailsTagDateHelper

  def validUntil = { attrs, body ->
    Date reservedAt = attrs.reservedAt
    String style = attrs.style ?: "SHORT"

    Locale locale = GrailsWebRequest.lookup().getLocale()
    if (locale == null) {
      locale = Locale.getDefault()
    }
    def timeZone = grailsTagDateHelper.getTimeZone()

    def dateFormat = grailsTagDateHelper.getDateFormat(style, timeZone, locale)

    DateTime expirationDateTime = new DateTime(reservedAt)
        .plusDays(expirationTime - 1)
        .withHourOfDay(23)
        .withMinuteOfHour(59)
        .withSecondOfMinute(59)
        .withMillisOfSecond(999)

    return grailsTagDateHelper.format(dateFormat, expirationDateTime.toDate())

  }

}

Although this might not be the answer that you are looking for, I hope this will help others with a similar problem!