我目前正在学习如何将Doctrine ORM与ZF2一起使用,目前我的目标是从简单的表连接中检索数据并将其显示在屏幕上。
我已阅读过这些文件,看起来很简单。
这些是我的表格:
user
------------------------
|user_id | name | email |
--------------------------
| 1 | John | j@b.com |
--------------------------
| 2 | Bob | b@j.com |
--------------------------
user_role_linker
--------------------------
|user_id | role_id |
--------------------------
| 1 | administrator |
--------------------------
| 2 | staff |
--------------------------
我想要实现的是我的观点列表如下:
ID Name Email Role Actions
--------------------------------------------------------
1 John j@b.com Administrator Edit
2 Bob b@j.com Staff Edit
--------------------------------------------------------
Paging goes here
----------------
这是我目前所拥有的,它似乎有效,但我不知道如何获取连接的表数据:
User entity::
<?php
namespace Administration\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\ManyToMany;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\Common\Collections\ArrayCollection;
/** @ORM\Entity */
class User {
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
protected $user_id;
/** @ORM\Column(type="integer", name="parent_id") */
protected $parent_id;
/** @ORM\Column(type="string", name="name") */
protected $name;
/** @ORM\Column(type="string", name="email") */
protected $email;
//Setters and getters
public function getUserId() {
return $this->user_id;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function getEmail() {
return $this->email;
}
public function setEmail($email) {
$this->email = $email;
}
/**
* @ManyToMany(targetEntity="UserRoleLinker")
* @JoinTable(
* name="user_role_linker",
* joinColumns={
* @JoinColumn(
* name="user_id",
* referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(
* name="user_id",
* referencedColumnName="id",
* unique=true)
* })
*/
private $role_id;
public function __construct()
{
$this->role_id = new ArrayCollection();
}
/** @return Collection */
public function getRoleId()
{
return $this->role_id;
}
}
用户角色链接器实体::
<?php
namespace Administration\Entity;
use Doctrine\ORM\Mapping as ORM;
/** @ORM\Entity */
class UserRoleLinker {
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
protected $user_id;
/** @ORM\Column(type="string", name="role_id") */
protected $role_id;
/** @param User|null */
public function getRoleId() {
return $this->role_id;
}
}
我的管理控制器::
public function usersAction() {
$em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$userFunctions = new UserFunction($em);
$userArray = $userFunctions->getUsers();
$viewModel = new ViewModel(array('users' => $userArray));
return $viewModel;
}
这会调用我的UserFunctions类::
public function getUsers()
{
//This function returns the users
return $this->em->getRepository('Administration\Entity\User')->findAll();
}
在我看来,我列出了这样的数据:
<?php
foreach ($this->users AS $user) {
?>
<tbody>
<tr class="odd gradeX">
<td width="5%"><?php echo $user->getUserId(); ?></td>
<td><?php echo $user->getName(); ?></td>
<td><?php echo $user->getEmail(); ?></td>
<td class="center">*** HOW DO I SHOW THE ROLE ?? ***</td>
<td>Edit</td>
</tr>
<?php } ?>
如何抓住要在视图中显示的角色?
答案 0 :(得分:0)
您必须在实体定义中定义用户和角色之间的正确关系。
我不知道你为什么在这里使用链接表。您是否希望在用户和角色之间实际拥有多对多关系(每个用户可以拥有多个角色?)。
如果没有,您可以轻松地将角色ID移动到用户表中,然后在用户和角色之间定义ManyToOne
关系。
您的用户表将如下所示:
-------------------------------------------
|user_id | name | email | role_id |
-------------------------------------------
| 1 | John | j@b.com | administrator |
-------------------------------------------
| 2 | Bob | b@j.com | staff |
-------------------------------------------
我建议以用户作为拥有方来查看ManyToOne
。您可以在the Doctrine2 documentation
之后,您只需在视图中拨打$user->getRole();
即可...
使用连接表修复一对多的答案:
doctrine documentation here...
中也对此进行了描述你需要三张桌子;用户表,角色表和用户角色 - 链接器表 用户是一个实体,角色是一个实体,角色 - 链接器表不是您的实体。您应该删除该实体,链接器表仅用于连接数据库中的用户和角色。
用户表
---------------------------
|id | name | email |
---------------------------
| 1 | John | j@b.com |
---------------------------
| 2 | Bob | b@j.com |
---------------------------
角色表
-----------------
| id |
-----------------
| administrator |
-----------------
| staff |
-----------------
| guest |
-----------------
| another role |
-----------------
链接表
--------------------------
|user_id | role_id |
--------------------------
| 1 | administrator |
--------------------------
| 2 | staff |
--------------------------
在您的用户实体中:
/** ONE-TO-MANY UNIDIRECTIONAL, WITH JOIN TABLE ONLY WORK WITH MANY-TO-MANY ANNOTATION AND A UNIQUE CONSTRAINT
* @ORM\ManyToMany(targetEntity="Administration\Entity\Role")
* @ORM\JoinTable(name="user_role_linker",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id", unique=true)}
* )
*/
protected $roles;
/**
* Get roles.
*
* @return ArrayCollection
*/
public function getRoles()
{
return $this->roles;
}
/**
* Add a role to the user.
*
* @param Role $role
*
* @return User
*/
public function addRole(Role $role)
{
$this->roles[] = $role;
return $this;
}
/**
* Remove a role from the user
*
* @param Role $role
*
* @return User
*/
public function removeRole(Role $role)
{
$this->roles->removeElement($role);
return $this;
}
您的角色实体:
/**
* An example entity that represents a role.
*
* @ORM\Entity
* @ORM\Table(name="role")
* @property string $id
*/
class Role
{
/**
* @var string
* @ORM\Id
* @ORM\Column(type="string", length=255, unique=true, nullable=false)
*/
protected $id;
/**
* Get the id.
*
* @return string
*/
public function getId()
{
return $this->id;
}
}
我认为这可以帮助你解决它......
也许您应该将以下内容添加到您的应用程序模块中:
public function doctrineValidate(MvcEvent $event){
$application = $event->getParam('application');
$serviceManager = $application->getServiceManager();
$entityManager = $serviceManager->get('doctrine.entitymanager.orm_default');
$validator = new SchemaValidator($entityManager);
$errors = $validator->validateMapping();
if (count($errors) > 0) {
// Lots of errors!
var_dump($errors);
}
}
然后在bootstrap:
$eventManager->attach('dispatch', array($this, 'doctrineValidate'));
在模块中: Doctrine将通过检查您的实体定义来帮助您。它可能会提前告诉您实体定义中存在问题......
答案 1 :(得分:0)
令人困惑,但正如您在实体中定义的那样,您可以使用用户实体 getRoleId 的功能获取角色集合。然后,对于每个 UserRoleLinker 实体,您还必须再次使用 getRoleId 函数,该函数将返回“管理员”或“员工”字符串。循环示例:
$roles = $user->getRoleId();
foreach ( $roles as $role ) {
$roleId = $role->getRoleId();
}
我建议你以另一种方式做。一个实体应为用户,并具有名为角色的属性。另一方面,您可以拥有实体角色。它们之间的链接应为One-To-Many, Unidirectional with Join Table( user_role_linker 表)。
答案 2 :(得分:0)
正如lluisaznar所建议的那样(虽然我需要多对一的关系,因为每个用户只有一个角色)。
我正在尝试以下方法:
<?php
namespace Administration\Entity;
//use stuff
/** @ORM\Entity */
class User {
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
//setters getters
/**
* @ManyToOne(targetEntity="Role")
* @JoinColumn(name="user_id", referencedColumnName="id")
*/
private $role;
public function __construct()
{
$this->role = new ArrayCollection();
}
/** @return Collection */
public function getRoleId()
{
return $this->role;
}
}
角色实体:
<?php
namespace Administration\Entity;
use Doctrine\ORM\Mapping as ORM;
/** @ORM\Entity */
class Role {
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
protected $user_id;
/** @ORM\Column(type="string", name="role_id") */
protected $role;
/** @param User|null */
public function getRoleId() {
return $this->role;
}
}
当我运行时,我收到以下通知:
Notice: Undefined index: id in trunk/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2611
和
Notice: Undefined index: user_id in trunk/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 121
此外,当我将$ user对象转储到角色下时,我没有显示该角色:
private 'role' =>
object(DoctrineORMModule\Proxy\__CG__\Administration\Entity\Role)[609]
public '__initializer__' =>
object(Closure)[595]
public '__cloner__' =>
object(Closure)[596]
public '__isInitialized__' => boolean false
protected 'user_id' => null
protected 'role' => null