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()
的函数,但以特定的方式期望该函数返回 HasMany
、HasOne
、BelongsTo
等. 样式关系对象。
请考虑 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 无法正确返回模型的关系