【问题标题】:How to manage a ManyToOne relation with symfony 2 and doctrine如何管理与 symfony 2 和学说的多对一关系
【发布时间】:2016-04-21 23:25:39
【问题描述】:

我目前正在发现 symfony 2 并在这个美妙的框架上训练自己。所以我有新手问题...

我按照本教程来管理与学说的关系: http://symfony.com/doc/current/book/doctrine.html

嗯,在我的测试中,我遇到了一个问题。

首先是问题: Symphony 最佳实践表明,在其他 .orm.yml 文件中最好使用注解而不是 yaml 进行教义映射。好,我完全同意这一点。 “使用注释很方便,允许您在同一个文件中定义所有内容”。所以如果我们选择使用注解,我猜我们不再需要 .orm.yml 映射文件了? 假设我有一个名为 userType 的表。我创建了一个实体类 userType.php 并直接在这个类中添加了带有注释的映射信息。我尝试的任何东西,添加语句:

use Doctrine\ORM\Mapping as ORM;

或者不在我的 userType.php 类中,symfony 显示这个错误:

No mapping file found named 'UserType.orm.yml' for class 'AppBundle\Entity\UserType

如果我不创建 UserType.orm.yml 文件。

所以这是我的问题:如果我们选择只使用注释,我们还需要一个 .orm.yml 映射文件吗?如果是,我们必须在此文件中放入的最少信息是什么?

第二点我的问题: 我的用户角色位于与用户表不同的表 (userType) 中。

+-------------------------------------------+-------------------------------------------+
|user                                       |   userType                                |
|id    username    password    userType_id  |   userType_id  label          role        |
|1     testuser    something   1            |   1            Administrator  ROLE_ADMIN  |
+-------------------------------------------+-------------------------------------------+

所以我想我需要在我的 user.php 实体类中添加一个 manyToOne 关系(许多用户只能拥有相同的一个角色)。

所以我在我的 User.orm.yml 映射文件中添加了这些行

(…)
manyToOne:
        userType:
            targetEntity: UserType
            joinColumn:
                name: userType_id
                referencedColumnName: userType_id
    lifecycleCallbacks: {  }
(…)

并像这样在我的 user.php 实体类中声明了 var userType

/**
*
*/
private $userType;

这是我的 userType.php 实体类文件:

    namespace AppBundle\Entity;

    use Doctrine\ORM\Mapping as ORM;

    /**
     * @ORM\Entity
     */
    class UserType
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer", name="userType_id")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;

        /**
         * @ORM\Column(type="string", name="label")
         */
        private $label;


        /**
         * @ORM\Column(type="simple_array", name="role")
         */
        private $role;


        public function getId()
        {
            return $this->id;
        }

        /**
         *
         */
        public function getLabel()
        {
            return $this->label;
        }
        public function setLabel($label)
        {
            $this->label = $label;
        }

        /**
         *
         */
        public function getRole()
        {
            return $this->role;
        }
        public function setRole($role)
        {
            $this->role = $role;
        }
}

还有我的 UserType.orm.yml 文件:

AppBundle\Entity\UserType:
    type: entity
    table: userType
    id:
        id:
            type: integer
            id: true
            column: userType_id
            generator:
                strategy: AUTO
    fields:
        label:
            type: string
            length: '150'
            column: label
        role:
            type: simple_array
            length: '100'
            column: role
    lifecycleCallbacks: {  }

好吧,我的 user.php 实体的 $userType var 似乎是一个包含 userType 数据的对象。 但是如果我做一个

var_export($this->userType, true);

$userType 对象我得到了这个:

Proxies\__CG__\AppBundle\Entity\UserType::
__set_state(array( '__initializer__' => Closure::
__set_state(array( )), '__cloner__' =>
Closure::__set_state(array( )), '__isInitialized__' =>
false, 'id' => 1, 'label' => NULL, 'role' => NULL, ))

只有字段 id 被填写,其他字段为 NULL。 如何获取对象 $userType 中的标签和角色字段值?我的错误是什么?

非常感谢您的帮助。

【问题讨论】:

  • 对于您的第一个问题:不,您不需要任何 .yml 文件进行映射。您是否在其他配置文件中的某处声明了 UserType.orm.yml 文件?您可以通过在整个项目中搜索字符串“UserType.orm.yml”来检查吗?
  • 感谢您的建议。这也是我的想法之一。但是在我的项目目录中搜索文本 UserType.orm.yml 不会返回任何结果。例如在日志文件(app/logs/dev.log)中有多个条目No mapping file found named UserType.orm.yml for class AppBundle\\Entity\\UserType type(正常)。我曾尝试使用此命令行$ php bin/console doctrine:generate:entities AppBundle 自动生成实体以检查生成的实体。也许它已经创建或更新了另一个配置文件,但我不知道

标签: php symfony orm doctrine


【解决方案1】:

感谢您的建议。他们帮了我很多。

我解决了我的两个问题。

对于我的 .orm 文件问题:确实正如 @chalasr 建议的那样,在删除 Resources/config/doctrine 文件夹后,Symphony 停止向我显示有关丢失 .orm 文件的错误。通过遵循@chalasr 其他提示,我设法停止使用 orm 文件。谢谢。

但我还有其他问题(只有“id”字段填写在 $userType 对象中,其他地方为 NULL)。 我注意到 $userType 对象没有初始化,它实际上是一个教义“延迟加载问题”。

这两个帖子帮助我解决了我的问题:

Get entities from a unidirectional many to many relation with Doctrine2 and Symfony2

doctrine2 association is not initialized

我将选项 fetch="EAGER" 添加到我的 ManyToOne 关系中,现在所有 $userType 对象字段都已完美填充。

这是我实际的 ManyToOne 关系(使用注释;-))

/**
     * @ORM\ManyToOne(targetEntity="UserType", fetch="EAGER")
     * @ORM\JoinColumn(name="users_types_id", referencedColumnName="users_types_id")
     */
    private $userType;

这就是我获得角色字段值的方式

/**
     * Returns the roles or permissions granted to the user for security.
     */
    public function getRoles()
    {

        $accessor_user_role = PropertyAccess::createPropertyAccessor();

        $roles = $accessor_user_role->getValue($this->userType, 'role');

        // guarantees that a user always has at least one role for security
        if (empty($roles)) {
            $roles[] = 'ROLE_USER';
        }

        return $roles;
    }

我希望我以这种方式继续尊重 Symfony 的良好做法。

非常感谢您的帮助。

【讨论】:

    【解决方案2】:

    不,您必须在这两种格式之间做出选择。

    你的实体有很多问题。

    您省略了@ORM\Table 语句,请使用:

    /**
     * @ORM\Entity
     * @ORM\Table(name="user_types")
     */
    class UserType
    {
        //...
    }
    

    然后,您必须将文件重命名为与其包含的类的名称相对应。

    您的类名为UserType,但包含它的文件名为userType.php
    根据PSR-0 standards,您必须改用UserType.php

    从文件系统加载时,每个命名空间分隔符都会转换为 DIRECTORY_SEPARATOR。
    [...]
    从文件系统加载时,完全限定的命名空间和类以 .php 为后缀。

    示例:App\AcmeBundle\Entity\User 将变为 src/App/AcmeBundle/Entity/User.php

    另外,我认为您在实体声明中省略了命名空间的一部分,添加缺少的捆绑命名空间的第一部分(如 PSR 所述,它应该是 src 之间的第一个文件夹的名称和你的AppBundle 目录)。

    如果您在使用注解之前已经开始使用 YAML,请执行以下过程:

    • 删除您的包的整个Resources/config/doctrine 目录(或仅删除与实体对应的映射文件)。
    • 使用php app/console doctrine:cache:clear-metadata 清除实体元数据的缓存
    • 使用php app/console cache:clear 清除应用程序缓存

    完成此操作后,使用正确的映射更新您的数据库架构:
    php app/console doctrine:schema:update --force

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 2022-01-11
      相关资源
      最近更新 更多