3

I'm trying to learn Grails but am still pretty much on beginner level. I made a tiny application, where you can basically add events, and people can write reviews about them and rate them. So I have an eventController and reviewController. The rating is just an Integer in a review. But now I want to show an overall rating for an event. So the events rating should be the average value of the corresponding ratings value.

This is my event domain code where the rating is initially set, I left out the constraints and toString:

class Event {
Double dRating = 2

static hasMany = [ratings:Rating]

}

The controller is simply:

class EventController {

def scaffold = Event
}

The rating domain file:

class Rating {
   String comment
   java.util.Date date = new java.util.Date()
   Integer rating
   Event event
}

and the Rating Controller is:

class RatingController {
    def scaffold = Rating
}

Hope I didn't make mistakes, I had to translate variable names so they're understandable.

I'm guessing that where dRating is set, I could somehow add some calculation, but I don't even know how to access the values of the rating, and everything I try ends in lots of errors and having to restart the app again and again. I tried adding calculations in the controller, but there I don't know how to get the value into the database. So where do I actually put the logic, and how do I access the values?

If any other file is important, please tell me.

Hoping to get some hints on how to start doing this, I didn't think it would be this hard.

Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
Silvie
  • 41
  • 1
  • 8

1 Answers1

1

At first I would recommend start reading grails doc. Later from your question it is not much clear what you are asking a there could be several places or possibilities of setting up the value in domain field and persist it to database. I'm telling all of these which are known to me:

  1. If it is generalised calculation that needs to be applied to your dRating field, then create a setter with standard bean naming convention and do this there. For example, you want to find percentage from say 1000 and then add it to dRating

    class Event {
    
     static hasMany = [ratings:Rating]
    
      Double dRating 
    
      void setDRating(Double value){
      this.dRating  = value * 100/1000 // alternatively value /10
     }
    }
    
  2. Do it in commandObject: If you don't want to put certain calculations and validation in domain then put these in command objects. See this. You can at any point of time assign values from command object to domain object by .properties binding mechanism. For example,

        yourDomainObject.properties = yourcommandObjectObject.properties
    

    Remember properties having same name would be binded.

  3. Do it in service: You can do your calculations in service method, inject that service into your controller and call that method to perform calculations and even to persist to db as well. Remember services are by default transactional.

Hope it helps!

Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
  • Thank you! I like the first option, but I need to access the values of the Ratings that are connected to the Event. Or would I call the function from another place, like when making a new Rating? – Silvie Jan 12 '16 at 13:25
  • 1
    you could do any level of manipulation there. you could use for example Event.findAll() in the setter. I would recommend trying and playing around and going through grails docs to learn it quickly. – Vinay Prajapati Jan 12 '16 at 13:27
  • 1
    you should be very careful while putting some logic in domain as there might be possible chances that you end up with a heavy domain and hence I would recommend using a service rather. But for highly coupled with domain scenarios use domain for such manipulations – Adesh Kumar Jan 12 '16 at 13:40
  • Adesh Kumar : Thanks for the hint. This is just a testing thing and I want it to do something easily. I might learn how to work services later, but for now that sounds too complicated for me. @Vinay Prajapati : findAll was a good hint. But my function "setDRating" is not executed, it seems. When I leave away the iniatilizing = 2 that I had, it gives an error (Message: Error mapping onto view [/index]: Error applying layout : main) Do I have to write a method call somewhere? – Silvie Jan 12 '16 at 13:51