我有两个代表用户(User
)和友情请求(FriendshipRequest
)的实体。 User和FriendshipRequest之间存在oneToMany关系,因此Doctrine在类User中创建一个名为getFriendshipRequests()
的方法。这没关系,但是FriendshipRequest有一个名为status的属性,所以我希望User类可以过滤与其关联的友情请求,以及其状态。我已经阅读了Doctrine文档,我发现了这个:
本地,您无法过滤2.0和2.1中的关联。你应该用 DQL查询以查询已过滤的实体集。
根据这个,我想我应该创建一个FriendshipRequest存储库并创建一个名为“findByStatusAndUser”的方法(或类似的东西),但我认为这是一个糟糕的解决方案。
我想在User实体中有一个方法,比如getPendingStatusRequests()
。这可能吗?如果不是,最好的解决方案是什么?
答案 0 :(得分:2)
从Doctrine 2.3开始,您可以使用matching and Criteria
然后,您可以在用户实体中使用getPendingStatusRequests()
,就像您想要的那样。
对于您的示例,代码如下所示:
public function getPendingStatusRequests()
{
$criteria = Criteria::create(); //don't forget to use Doctrine\Common\Collections\Criteria;
$criteria->where(Criteria::expr()->eq('status', 1));
return $this->friendshipRequests->matching($criteria);
}
答案 1 :(得分:1)
我认为FriendshipRequest存储库中的“getPendingRequestsForUser($ user)”方法应该是一个很好的解决方案。在这个方法中你只需要创建一个合适的DQL。
这是一个很好的解决方案,因为所有逻辑都应该移动到存储库,使实体尽可能小而干净。
UPD:另外,您可以使用findBy方法,如前所述here,例如:
$pendingRequests = $em->getRepository('MyBundle:FriendshipRequest')->findBy(
array('user' => $user->getId(), 'status' => 1)
);
但对我来说,首选方法是首选。
答案 2 :(得分:0)
您当然可以将getPendingStatusRequests()添加到用户,然后让它循环遍历所有友谊请求,并仅返回具有相应状态的请求。
唯一的潜在问题是所有的友情请求都将被加载,包括那些你不需要的。由您来决定这是否是一个真正的问题。可能是一旦处理了友谊请求,它就会被删除,因此用户在任何给定时间都不会有很多请求。
如果您确实希望避免加载所有请求,请进行查询并在join子句中使用WITH表达式。类似的东西:
$qb->leftJoin('user.friendshipRequests','request',
Expr\Join::WITH, $qb->expr()->eq('request.status', $qb->expr()->literal('Pending')));
由于您使用的是S2,我不会愚弄存储库。只需创建一个名为UserManager的服务,注入实体管理器,并为其提供一个名为loadUserWithPendingFriendshipRequests的方法。