Laravel 模型必须返回一个关系实例

Posted

技术标签:

【中文标题】Laravel 模型必须返回一个关系实例【英文标题】:Laravel Model must return a relationship instance 【发布时间】: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 这回答了“哪里”。怎么样? 【参考方案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

以上是关于Laravel 模型必须返回一个关系实例的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent ORM 无法正确返回模型的关系

laraver框架学习------工厂模型填充测试数据

Laravel Eloquent发现并返回两种不同的类型?

Laravel:每当我返回一个模型时,总是返回一个与它的关系

Laravel 动态关系 - 在急切加载时访问模型属性

如何用他在 Laravel 中的关系返回一个模型?