Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Model must return a relationship instance

Tags:

laravel

My website has comments. These comments can have "votes", upvotes and downvotes.

I have a Comment Model and a CommentVote model.

In my comment model I have a functions that returns the votes:

public function votes() {
    return $this->hasMany('App\CommentVote', 'comment_id');
}

public function upvotes() {
    return $this->hasMany('App\CommentVote', 'comment_id')->where('vote', 1);
}   

public function downvotes() {
    return $this->hasMany('App\CommentVote', 'comment_id')->where('vote', -1);
}       

Notice that upvotes are stored in the database in a tinyInt as 1 and downvotes are stored as -1

In my CommentVote model I have the belongsTo relationship:

public function comment() {
    return $this->belongsTo('App\Comment');
}   

Now I want to have a function that calculates the total "score" of the comment. Total upvotes minus total downvotes.

I try to make a function that counts all the upvotes - all the downvotes.

public function score() {
    return $this->upvotes()->count() - $this->downvotes()->count();
}   

This returns the error:

App\Comment::score must return a relationship instance.

In fact using the count() anywhere will return this error, despite it working fine in my other Models.

Doing something simple like:

public function voteCount() {
    return $this->hasMany('App\CommentVote', 'comment_id')->count();
    or even
    return $this->votes()->count();
}   

will return the error:

App\Comment::voteCount must return a relationship instance.

Why is this happening?

EDIT:

Here is the controller, as per requests in the comments:

public function getSubmission($subchan, $id, $URLtitle) {

    $submission = Submission::where('id', $id)->first();
    $comments = Comment::where('submission_id', $submission->id)->where('parent_id', NULL)->orderBy('created_at', 'desc')->get();

    $comments = $comments->sortByDesc(function($comment){
        return count($comment['upvotes']) - count($comment['downvotes']);
    });     

    if (!$submission) {
        return redirect()->route('home')->with('error', 'Submission not found.' );
    }       

    return view('submissions.submission')
    ->with('submission', $submission)
    ->with('navSubchan', $submission->getSubchan->name)
    ->with('submissionPage', 1)
    ->with('comments', $comments)
    ;

}   
like image 568
Felix Maxime Avatar asked Oct 28 '25 03:10

Felix Maxime


1 Answers

I suspect you're doing $model->score, which is going to look for a function called score(), but in a specific manner that expects that function to return a HasMany, HasOne, BelongsTo etc. style relationship object.

Consider an accessor function instead.

public function getScoreAttribute() {
    return $this->upvotes()->count() - $this->downvotes()->count();
}

allows you to do $model->score successfully.

like image 159
ceejayoz Avatar answered Oct 29 '25 17:10

ceejayoz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!