背景
想象一组提案,每个用户都可以为提案投赞成或反对票。
所以我有两个模型:
- 一个
Proposal(提案)
, - 一个与
proposal
、user
和opinion
(赞成或反对)相关的Vote(投票)
。
现在我想要显示所有的提案,包括每个提案的额外信息:
- 有多少个赞成票?
- 有多少个反对票?
- 当前用户是否已经赞成?
- 当前用户是否已经反对?
问题
这很容易实现,但这意味着每次显示提案都需要4个请求(称为n+1查询问题)。 我来自Rails世界,在那里可以使用急切加载或一些巧妙的查询轻松解决这个问题。但我无法用doctrine解决它,需要一些帮助!
我尝试过的方法
使用神奇字段
第一种解决方案是制作自定义查询:选择所有提案,包括赞成票数、反对票数、当前用户是否已经赞成或反对。
查询现在返回比模型描述多4个列:count_upvotes
、count_downvotes
、has_user_upvoted
和 has_user_downvoted
。
为了能够与doctrine一起使用,我必须将这些字段添加到我的Proposal
实体中。
对我来说,这不是一个好的解决方案,因为它意味着必须始终使用此查询以避免混乱的模型,其中这些字段可能为空。
使用摘要
第二种解决方案是创建另一个对象供视图使用。该对象是由当前用户作为参数创建的。该对象通过优化的查询创建,并包含以下方法:
getAllProposals()
getUpvotes($a_proposal)
getDownvotes($a_proposal)
hasUserUpvoted($a_proposal)
hasUserDownvoted($a_proposal)
对我来说,为了视图优化而被迫创建一个对象确实有点过度。
使用扩展实体
这第三种解决方案使用唯一的查询获取提案、它们的赞成票、反对票,并检查用户是否已经赞成或反对。
它创建了一个新的“扩展”实体,
public function __construct(
Proposal $badgeProposal,
$upvotesCount,
$downvotesCount,
$hasUserUpvoted,
$hasUserDownvoted
) {
对我来说,这是更好的解决方案,但目前无法实现,因为我不知道如何从SQL行中简单地填充提议(但我正在努力寻找)。
你的回合
那么,还有其他解决方案吗?这应该是Doctrine开发人员熟知的问题。
SUM
等函数。 - kero