我的应用程序需要有条件地操作查询。详细说明;如果当前登录的用户不是管理员,则需要限制查询的结果集。
我真的不喜欢我现在正在重复多少,我已经知道这样做很糟糕,但是这里有:
我的一个控制器的一个例子:
try {
if ($sc->isGranted('ROLE_ADMIN')) {
$gallery = $gr->findById($id); // If the user is an admin, show all
} else {
$gallery = $gr->findActiveById($id); // Otherwise, show only active ones
}
} catch (NoResultException $e) {
throw $this->createNotFoundException('That gallery doesn\'t exist!');
}
你可能已经猜到了$gr
这个存储库中发生了什么。以下是来自所述存储库的2个方法:
public function findById($id)
{
$dql = '
SELECT
g,
gci,
gi,
t,
gv
FROM
DWIPortfolioBundle:Gallery AS g
LEFT JOIN
g.coverImage AS gci
LEFT JOIN
g.images AS gi
LEFT JOIN
g.tags AS t
LEFT JOIN
g.views AS gv
WHERE
g.id = :id';
$query = $this->getEntityManager()->createQuery($dql)
->setParameter('id', $id);
return $query->useResultCache(true)
->getSingleResult();
}
public function findActiveById($id)
{
$dql = '
SELECT
g,
gci,
gi,
t,
gv
FROM
DWIPortfolioBundle:Gallery AS g
LEFT JOIN
g.coverImage AS gci
LEFT JOIN
g.images AS gi
LEFT JOIN
g.tags AS t
LEFT JOIN
g.views AS gv
WHERE
g.id = :id
AND
g.isActive = 1';
// ^^^^^^^^^^^^^^^^^^^^
// This last 'AND' bit is the only part that is
// different from the method above this
$query = $this->getEntityManager()->createQuery($dql)
->setParameter('id', $id);
return $query->useResultCache(true)
->getSingleResult();
}
所以,我的问题是,我应该怎么做这个干?我知道我不应该注入用户,安全上下文或任何类似的东西,因为这个存储库应该只关注自己。但是我很难想到处理查询操作的最佳方法(我不反对使用QueryBuilder,如果需要这样做可以使这个结构更好一些)。
答案 0 :(得分:1)
您可以添加第二个参数,并在QueryBuilder
方法中使用findById
。
public function findById($id, $is_active=false) {
$qb = $this->getEntityManager()->createQueryBuilder();
$query = $qb->select("g, gci, gi, t, gv")
->from("DWIPortfolioBundle:Gallery", "g")
->leftJoin('g.coverImage', 'gi')
// ....
->where('g.id = :id')
->setParameter('id', $id);
if ($is_active) {
$query->andWhere('g.isActive = 1');
}
return $query->getQuery()->useResultCache(true)->getSingleResult();
}
我想更多DRY-way将是一个单一的函数,它使用某种$options
数组来检索显示图库的许多可能方式:
public function getGallery($options) {
$qb = $this->getEntityManager()->createQueryBuilder();
$query = $qb->select("g")
->from("DWIPortfolioBundle:Gallery", "g");
if ($options) {
if (isset($options['id'])) {
$query->andWhere('g.id = :id')->setParameter('id', $options['id']);
}
if (isset($options['is_active'])) {
$query->andWhere('g.isActive = :is_active')->setParameter('is_active', $options['is_active']);
}
if (isset($options['limit'])) {
$query->setMaxResults($options['limit']);
}
// Any other filtering options you might need
}
return $query->getQuery()->useResultCache(true)->getResult();
}