GrailsInAction / graina2

Source code for the 2nd edition of Grails in Action
90 stars 93 forks source link

Unable to retrieve/save posts on timeline #105

Open carljenkins opened 10 years ago

carljenkins commented 10 years ago

When working through section 6.4.2 I can't seem to get the timeline.jsp to update with the saved post submitted by the form. The only way to get it to work was to add a post.save(flush:true) after the if(user.save()) statement. If I take the post.save() out the page doesn't update with the newly created post.

I noticed someone else had a similar problem around Dec 2013. Is this still a problem or am I missing something basic?

 def addPost() {
    def user = User.findByLoginId(params.id)
    if (user) {
        def post = new Post(params)

        user.addToPosts(post)
        if (user.save()) {
            post.save(flush: true)
            flash.message = "Successfully created Post"
        } else {
            flash.message = "Invalid or empty post"
        }
    } else {
        flash.message = "Invalid User Id"
    }
    redirect(action: 'timeline', id: params.id)
}

java version 1.7.0_51 grails version 2.4.0

pledbrook commented 10 years ago

Do you have this line in your Post.groovy domain class?

pledbrook commented 10 years ago

To clarify the previous comment, the user.save() call will also save any new posts that have been added to the user as long as Post belongs to User.

carljenkins commented 10 years ago

Hi - thanks for the reply. Yes, I do have that line in my Post.groovy. Here is what my Post domain looks like right now.

package com.grailsinaction

class Post {
  String content
  Date dateCreated

  static constraints = {
  }
  static belongsTo = [user : User]
  static hasMany = [tags : Tag]
  static mapping = {
      sort dateCreated: "desc"
  }
  }
pledbrook commented 10 years ago

Which version of Grails are you using? I remember testing this several times, so unless the Post is failing validation (which it can't be if your post.save() is working) then I can only think of a version issue.

Have you downloaded the chapter source and tested that with ./grailsw run-app?

I'm afraid I don't have time to look at this right now. Maybe later in the week.

carljenkins commented 10 years ago

I am currently running Grails version 2.4.0. I will do as you suggest and try running the chapter source and see what that does; I'll post back here the outcome of running that.

Thanks for your help.

edit: My apologies for taking so long to reply. I ran the chapter code as you suggested and indeed it works correctly. Appears I have some kinks to work out. Thanks for your help!

thiagoa commented 9 years ago

I'm using Grails 2.3.11 and MySQL.

That code sample worked for me when I submitted valid post content.

Instead, a problem happened when the post content was empty. I expected to see "Invalid or empty post", but instead I got a strange error from Hibernate, related to session flush in the event of an exception. I investigated the issue and found out the cause of the exception: validation does not cascade to child objects. When I saved the user, it tried to save the associated post without validation, but it failed badly because content had a NOT NULL constraint in MySQL.

I wrote some tests, and to make the code sample work "as is", I found a workaround in User.groovy:

static constraints = {
    ...
    posts validator: { posts ->
        posts ? posts.every { it.validate() } : true
    }
}

That forces User to validate child Post objects, if any. I expected Grails to do cascade vaildation, so I'm a bit disappointed. Is there a clean workaround for this? Am I missing something?