grails - 具有自定义多对多关系,带有参数的关系表的Grails

标签 grails spring-security many-to-many

我有以下 Realm :评论,Secuser和评级。

我希望每个评论可由SecUser +1或-1评分一次。在相关评论(针对 Realm 讨论)的 View 中,我希望有一个按钮可以向上或向下投票并刷新 View 。
我到目前为止的代码:
评论 View :

<tbody>
    <g:each in="${comments}" var="comm">
        <tr>
            <td>${comm.comment}</td>
            <td>${comm.commentBy}</td>
            <td><g:formatDate format="dd.MM.yyyy HH:mm" date="${comm.createDate}"/> </td>
            <td><button type="button" class="btn btn-default btn-lg" onclick="${remoteFunction(action: 'ratePositiveComment', update: 'content', params:[commentID:"${comm.id}"])}"><span class="glyphicon glyphicon-thumbs-up" aria-hidden="false" style="float:right">${comm.numberPositiveRatings}</span></button>
                &nbsp;
                <button type="button" class="btn btn-default btn-lg" onclick="${remoteFunction(action: 'rateNegativeComment', update: 'content', params:[commentID:"${comm.id}"])}"><span class="glyphicon glyphicon-thumbs-down" aria-hidden="false" onclick="addRating(-1, ${comm.id})" style="float:right">${comm.numberNegativeRatings}</span></button>
            </td>
        </tr>
    </g:each>
</tbody>

评论 Controller :
class Comments {
    static belongsTo = Discussion
    Discussion discussion
    SecUser commentBy
    String comment
    Date createDate = new Date()
    static hasMany = [commRatings : Rating]

    public long getNumberPositiveRatings() {
    return  Rating.countByCommentRatedAndRate(this, 1);
    }

    public long getNumberNegativeRatings() {
        return  Rating.countByCommentRatedAndRate(this, -1);
    }

    List raters() {
        return commRatings.collect{it.ratingUser}
    }

    List addToPosRatingUser(SecUser user) {
        Rating.positiveRating(user, this)
        //return raters()
    }

    List addToNegRatingUser(SecUser user) {
        Rating.negativeRating(user, this)
       // return raters()
    }

评级域:
class Rating {
    static belongsTo = Comments
    int rate
    SecUser ratingUser
    Comments commentRated

    static Rating positiveRating(ratingUser, commentRated) {
        def m = Rating.findByRatingUserAndCommentRated(ratingUser, commentRated)
        if (!m) {
            m = new Rating()
            ratingUser?.addToRating(m)
            commentRated?.addToRating(m)
            m.rate = 1;
            m.save()
        }
        return m
    }

    static Rating negativeRating(ratingUser, commentRated) {
        def m = Rating.findByRatingUserAndCommentRated(ratingUser, commentRated)
        if (!m) {
            m = new Rating()
            ratingUser?.addToRating(m)
            commentRated?.addToRating(m)
            m.rate = -1;
            m.save()
        }
        return m
    }
}

在域SecUser(Spring安全插件)中,我添加了:
class SecUser {

    transient springSecurityService

    String username
    String password
    String userEmail
    boolean enabled = true
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    static hasMany = [ratings:Rating]

    List ratedComments() {
        return ratings.collect{it.commentRated}
    }

    List addPosCommentRating(Comments comm) {
        Rating.positiveRating(this, comm)
        return ratedComments()
    }

    List addNegCommentRating(Comments comm) {
        Rating.negativeRating(this, comm)
        return ratedComments()
    }

CommentsController是脚手架,唯一添加的功能是:
def ratePositiveComment() {
    def rater = SecUser.findById(springSecurityService.currentUser.id);
    if(rater!=null) {
        Comments comm = Comments.get(params.commentID);
        comm.addToPosRatingUser(rater);
        comm.save();
    }
}


def rateNegativeComment() {
    def rater = SecUser.findById(springSecurityService.currentUser.id);
    if(rater!=null) {
        Comments comm = Comments.get(params.commentID);
        comm.addToNegRatingUser(rater);
        comm.save();
    }
}

我得到的错误代码是:
No signature of method: ForumProject.SecUser.addToRating() is applicable for argument types: (ForumProject.Rating) values: [ForumProject.Rating : (unsaved)]
Possible solutions: addToRatings(java.lang.Object). Stacktrace follows:
Message: No signature of method: ForumProject.SecUser.addToRating() is applicable for argument types: (ForumProject.Rating) values: [ForumProject.Rating : (unsaved)]
Possible solutions: addToRatings(java.lang.Object)

最佳答案

addTo(和removeFrom)方法是从hasMany映射中的名称派生的。如果您已经声明

static hasMany = [rating:Rating]

那么addTo方法将为addToRating,您的代码将是正确的。现在,您只需要将调用更改为addToRatings即可。

ps这不好:
def rater = SecUser.findById(springSecurityService.currentUser.id);
springSecurityService.currentUser已经是您想要的,它是登录时用于创建SecUserAuthentication,它是通过查询而不是从某些缓存从数据库中检索的。但是您在获得id后将其丢弃,因此可以使用效率低下的动态查找器再次加载它。始终使用get而不是findById。所以你的代码应该只是
def rater = springSecurityService.currentUser

关于grails - 具有自定义多对多关系,带有参数的关系表的Grails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30018481/

相关文章:

python - 通用多对多关系

mysql - 获取页面 block

grails - 在Grails中创建阻止的用户拦截器

grails - 如何将 grails 项目导入 Intellij 13.1 IDEA?

spring - 在 Spring security 中是否可以仅使用 HTTPS 进行登录?

spring - 自定义登录 + Spring Security + Tiles + 请求方法 'POST' 不支持

java - JPA:两个实体之间存在多个多对多关系?

grails - Controller 中的Grails错误处理

web-services - Grails 2.4.4中使用RESTFUL Web服务的登录页面

java - 模拟@AuthenticationPrincipal 参数