我正在尝试使用Symfony2 /{user}/{project}
匹配GitHub样式的网址(@ParamConverter
)。他们检索正确的实体,但我想确保该项目属于URL中的用户。这两个实体之间存在着一种学说关系。
例如,对于属于'foo'的项目'bar',我可以在/foo/bar
访问它。但是,我也可以在其他用户下访问它:/baz/bar
。
是否可以使用ParamConverter执行此操作,还是需要手动签入操作?
/**
* @Route("/{user}")
* @ParamConverter("user", class="AcmeUserBundle:User", options={"mapping": {"user": "usernameCanonical"}})
*/
class ProjectController extends Controller
{
/**
* @Route("/{project}")
* @ParamConverter("project", class="AcmeProjectBundle:Project", options={"mapping": {"project": "slug"}})
* @Template()
*/
public function showAction(User $user, Project $project)
{
// Can I automate this check?
if ($user->getId() !== $project->getOwner()->getId()) {
throw $this->createNotFoundException();
}
}
}
答案 0 :(得分:3)
找到解决方案,主要归功于@ Qoop的评论。通过向映射添加"user": "owner"
,使用$user
变量查询所有者关系(由于第一个@ParamConverter
,该变量已经是用户实例。
在幕后,这会发出两个查询 - 一个用于检索第一个用户,另一个用于检索项目(使用project.owner_id = user.id和project.slug = slug)。但是我认为这些可以在Doctrine级别进行缓存。
访问(不存在)/ baz / bar的结果是404,其中包含以下消息:
AcmeProjectBundle:找不到项目对象。
/**
* @Route("/{user}")
* @ParamConverter("user", class="AcmeUserBundle:User", options={"mapping": {"user": "usernameCanonical"}})
*/
class ProjectController extends Controller
{
/**
* @Route("/{project}")
* @ParamConverter("project", class="AcmeProjectBundle:Project", options={"mapping": {"user": "owner", "project": "slug"}})
* @Template()
*/
public function showAction(User $user, Project $project)
{
// Do something with $user and $project,
// where $project->getOwner() === $user
}
}