【问题标题】:Laravel Model must return a relationship instanceLaravel 模型必须返回一个关系实例
【发布时间】:2019-11-27 12:33:57
【问题描述】:

我的网站有 cmets。这些 cmets 可以有“投票”、赞成票和反对票。

我有一个评论模型和一个评论投票模型。

在我的评论模型中,我有一个返回投票的函数:

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);
}       

请注意,upvotes 以 1 形式存储在数据库中的 tinyInt 中,downvotes 以 -1 形式存储

在我的 CommentVote 模型中,我有 belongsTo 关系:

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

现在我想要一个计算评论总“分数”的函数。赞成票总数减去反对票总数。

我尝试创建一个计算所有赞成票 - 所有反对票的函数。

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

这会返回错误:

App\Comment::score 必须返回一个关系实例。

事实上,在任何地方使用count() 都会返回此错误,尽管它在我的其他模型中运行良好。

做一些简单的事情,比如:

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

将返回错误:

App\Comment::voteCount 必须返回一个关系实例。

为什么会这样?

编辑:

这是控制器,根据 cmets 中的请求:

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)
    ;

}   

【问题讨论】:

  • 您在哪里以及如何使用public function score()public function voteCount()
  • 评论模型
  • 我的意思是调用这些函数的代码是什么样的? Comment::with(["score"])? $score = $comment->score?等等等等
  • @FelixMaxime 这回答了“哪里”。怎么样?

标签: laravel


【解决方案1】:

我怀疑你在做 $model->score,它会寻找一个名为 score() 的函数,但以特定的方式期望该函数返回 HasManyHasOneBelongsTo 等. 样式关系对象。

请考虑 an accessor function

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

允许你成功地做$model->score

【讨论】:

  • 那么你需要告诉我们你是怎么称呼它的,因为那没有意义。您必须执行 $model->load('score') 之类的操作或使用 with('score') 进行急切加载。
  • @FelixMaxime 可能不是模型。这是您尝试输出/使用 score 值的地方 - 可能是控制器或视图。
  • 在你使用这些函数的地方发布控制器(或视图)代码。
  • @FelixMaxime 您发布的新代码在任何地方都没有“分数”一词。 我们需要以某种方式使用分数的代码。 获取它的值,打印它的值,等等。
  • 你并没有真正地调用comment->getScoreAttribute... Laravel 将函数名翻译成属性,所以对于get{...}Attribute,你可以调用任何...,所以$comment->score
猜你喜欢
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 2017-05-16
  • 2018-01-17
  • 1970-01-01
相关资源
最近更新 更多