Search code examples
grailsgrails-4

Grails - How to access configuration values in domain classes?


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)


Solution

  • 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!