0

I need to access the domain class User of the current session. The following code works:

class RatingController {    
def rate = {
    def rating = params.rating
    def artist = Artist.get( params.id )
    def user = User.get(1)
    user.addToRatings(new Rating(artist:artist, rating:rating))
    user.save()
    render(template: "/artist/rate", model: [artist: artist, rating: rating])
}
}

But instead of explicitly get the user with ID equal 1 (User.get(1)) I need to access the user of the current session. I tried the following code, but it doesn't work:

class RatingController {    
def rate = {
    def rating = params.rating
    def artist = Artist.get( params.id )
    def user = user.session
    user.addToRatings(new Rating(artist:artist, rating:rating))
    user.save()
    render(template: "/artist/rate", model: [artist: artist, rating: rating])
}
}

I'm still struggling to fully understand the httpSession concept, so a little help would be great. Thank in advance.

UPDATE

In my UserController, my authentication looks like this:

def authenticate = {
  def user = User.findByLoginAndPassword(params.login, params.password)
  if(user){
    session.user = user
    flash.message = "Hello ${user.name}!"
    redirect(controller:"event", action:"list")
  }else{
    flash.message = "Sorry, ${params.login}. Please try again."
    redirect(action:"create")
  }
}
Bruno Morgado
  • 507
  • 1
  • 8
  • 26
  • are you putting the user on the session? are you using some authentication mechanism that will provide it? – hvgotcodes Jun 24 '11 at 15:43
  • based on your edits, manipulate the session as I described in my answer. You need a string key. Do `session['SESSION_USER'] = user` and then `session['SESSION_USER']`. You probably want to define the string SESSION_USER as a constant in your application. – hvgotcodes Jun 24 '11 at 16:09
  • I tried to do that, but it throws the exception: "a different object with the same identifier value was already associated with the session". – Bruno Morgado Jun 24 '11 at 16:39
  • then test before you set it. `if (session['userkey'] != null) {//set}` – hvgotcodes Jun 24 '11 at 17:24
  • when you put objects on your session, you need to make them implement Serializable. When you reference a domain object, taken from a session, they are not attached to the Hibernate session, and you need to re-attach them, before you can save them again. This is done by: user.attach() – sbglasius Jun 27 '11 at 07:59

3 Answers3

3

the http session is nothing more than data that is maintained among a sequence of requests from a single source, like a browser.

To put something on the session, just do

session.setAttribute("key", value)

and to get data off the session just do

session.getAttribute("key")

Grails also adds some fanciness to session access as outlined here. Their example shows

def user = session["user"]
session["user"] = "John"
asset "John" == session.user

Note that if you are using a grails plugin for authentication and authorization, it will probably provide a way to get the user. For example Spring Security gives you the following

springSecurityService.getCurrentUser()

depending on the details of your plugin, that user might or might not be on the session.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
2

In your code I noticed you wrote

def user = user.session

When I think you mean

def user = session.user

The other thing I do is make it session.userId ie session.userId = user.id and then

def user = User.get(session.userId)

Not sure if that's necessary.

Mikey
  • 4,692
  • 10
  • 45
  • 73
1

You'll need to use .merge():

user.merge(flush: true)

This is because the instance is detached from the persistence context when you save it to HttpSession. Here is the doc from grails: http://grails.org/doc/2.3.1/ref/Domain%20Classes/merge.html

SystemR
  • 313
  • 2
  • 7