版本5:在null和其他持久性问题上调用成员函数sum()


Laravel 5: Call to a member function sum() on null and other persistence issues

我有一个线程评论列表,每个使用jquery.upvote.js的upvote/downvote按钮。

投票操作是通过ajax完成的,它的工作原理,使upvote或downvote在数据库中以正确的值注册。删除投票将从数据库中删除该记录。因此,从技术上讲,它可以按预期工作。

但是,我有两个问题:

  1. 用户所做的投票不会在页面重新加载后持续存在,这很重要,否则用户将不知道他们投票了什么。
  2. 当我将{{ $each_comment->commentvotes->sum('value') }}代码块添加到视图中以获取给定评论的投票总数时,我得到以下错误:

在null上调用成员函数sum()

路线

Route::resource('votes', 'VotesController');
Route::resource('commentvotes', 'CommentVotesController');

我想指出的是,我已经使用相同的方法成功地使用了Vote模型和VoteController对帖子的投票。

CommentVote模型

class CommentVote extends Model
{
    protected $table = 'commentvotes';
    protected $fillable = [
        'value',
        'comment_id',
        'user_id'
    ];
    public function user() {
        return $this->belongsTo('App'User');
    }
    public function posts() {
        return $this->belongsTo('App'Comment');
    }
}

CommentVotesController

class CommentVotesController extends Controller
{
    public function __construct() {
        $this->middleware('auth', ['only' => ['create', 'edit'] ]);
    }
    public function store(Requests'CommentVoteRequest $request)
    {
        $commentId = $request->input('commentId');
        $userId = $request->user()->id;
        $value = $request->input('value');
        // Check to see if there is an existing vote
        $vote = CommentVote::whereCommentId($commentId)->whereUserId($userId)->first();
        if (!$vote)
        {
            // First time the user is voting
            CommentVote::create(['comment_id' => $commentId, 'user_id' => $userId, 'value' => $value]);
        } else {
            $vote->value == $value ? $vote->delete() : $vote->update(['value' => $value]);
        }
        // AJAX JSON RESPONSE
        return response()->json(['status' => 'success',
            'msg' => 'Vote has been added.']);
    }
}
Javascript

$(document).ready(function() {
        $('.topic').upvote();
        $('.comment').upvote();
        $('.vote').on('click', function (e) {
            e.preventDefault();
            var $button = $(this);
            var postId = $button.data('post-id');
            var value = $button.data('value');
            $.post('http://localhost/r2/public/votes', {postId:postId, value:value}, function(data) {
                if (data.status == 'success')
                {
                    // Do something if you want..
                }
            }, 'json');
        });
        $('.commentvote').on('click', function (e) {
            e.preventDefault();
            var $button = $(this);
            var commentId = $button.data('comment-id');
            var value = $button.data('value');
            $.post('http://localhost/r2/public/commentvotes', {commentId:commentId, value:value}, function(data) {
                if (data.status == 'success')
                {
                    // Do something if you want..
                }
            }, 'json');
        });
    });

视图的相关部分comment_list.blade.php

@foreach($comments as $each_comment)
<div class="col-md-1">
    <div class="upvote comment" data-comment="{{ $each_comment->id }}">
        <a class="upvote commentvote {{ $each_comment->commentvotes && $each_comment->commentvotes->contains('user_id', Auth::id()) ? ($each_comment->commentvotes->where('user_id', Auth::id())->first()->value > 0 ? 'upvote-on' : null) : null}}" data-value="1" data-comment-id="{{ $each_comment->id }}"></a>
        <!-- Notice how we set the sum of the votes for this post here -->
        <span class="count">{{ $each_comment->votes->sum('value') }}</span>
        <a class="downvote commentvote {{ $each_comment->commentvotes && $each_comment->commentvotes->contains('user_id', Auth::id()) ? ($each_comment->commentvotes->where('user_id', Auth::id())->first()->value < 0 ? 'downvote-on' : null) : null}}" data-value="-1" data-comment-id="{{ $each_comment->id }}"></a>
    </div>
</div>
@endforeach

您必须在Comments模型中定义关系。否则评论实体将无法访问CommentVotes。