【问题标题】:Symfony3: Database and Entity settings: Neither property … nor method …nor method … exists in classSymfony3:数据库和实体设置:类中既不存在属性……也不存在方法……也不存在方法……
【发布时间】:2016-01-29 10:14:24
【问题描述】:

我知道有类似的问题,但没有一个解决方案适用于 Symfony 3.x。

所以我有三个实体,用户、角色和权限。用户具有角色(多对多)和权限(也是多对多)。然后我有一个表单,虽然权限工作正常,但角色却不行。

我能看到的唯一区别是,返回角色的函数没有按照应有的方式调用 getRoles(?),因为具有此名称的函数必须返回字符串数组(而不是角色实体数组)才能满足预期AdvancedUserInterface,这就是为什么另一个函数 (getRoleEntities) 返回 $this->roles,但我相信我在构建表单时反映了它。

这是用户实体类的简化版本:

/**
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */
class User implements AdvancedUserInterface, \Serializable {
    //id, username, personalname, password, email and isactive ommited

    /**
     *
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Permission", cascade = {"persist"})
     * @ORM\JoinTable(name="user_permission")
     */
    private $permissions;//this works

    /**
     *
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Role", cascade = {"persist"})
     * @ORM\JoinTable(name="user_role")
     */
    private $roles;//this doesn't work


    public function __construct() {
        $this->permission = new ArrayCollection();
        $this->roles = new ArrayCollection();
    }

    //irrelevant getters/setters ommited

    /**
     * Add Permission
     *
     * @param \AppBundle\Entity\Permission $userPermission
     *
     * @return User
     */
    public function addPermission(\AppBundle\Entity\Permission $userPermission) {
        $this->permissions[] = $userPermission;
        return $this;
    }

    /**
     * Remove Permission
     *
     * @param \AppBundle\Entity\Permission $userPermission
     */
    public function removePermission(\AppBundle\Entity\Permission $userPermission) {
        $this->permissions->removeElement($userPermission);
    }

    /**
     * Get Permissions
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getPermissions() {
        return $this->permissions;
    }

    ////////////////////////////////
    //roles

    /**
     * Add role
     * @param \AppBundle\Entity\Role $role
     *
     * @return User
     */
    public function addRoleEntity(\AppBundle\Entity\Role $role) {
        $this->roles[] = $role;
        return $this;
    }

    /**
     * Remove role
     * @param \AppBundle\Entity\Role $role
     */
    public function removeRoleEntity(\AppBundle\Entity\Role $role) {
        $this->roleRoles->removeElement($role);
    }

    /**
     * I know this one should simply return $this->roles, but it has to return array of strings to meet expectations of the AdvancedUserInterface, that is why another function (getRoleEntities) returns $this->roles
     * @return array
     */
    public function getRoles() {
        $ret_val = array();
        $roles = $this->getRoleEntities();

        if ($roles) {
            foreach ($roles as $role) {
                $ret_val[] = $role->getRoleName();
            }
        }
        return $ret_val;
    }

    /**
     * Get roles
     */
    public function getRoleEntities() {
        return $this->roles;
    }

}

这是我构建表单的方式:

    $em = $this->getDoctrine()->getManager();
    $user = $em->find('AppBundle:User',1);//just for testing


    $form = $this->createFormBuilder($user)
        ->add('personal_name', \Symfony\Component\Form\Extension\Core\Type\TextType::class, array('label' => 'Imię i nazwisko: '))
        ->add('is_active', \Symfony\Component\Form\Extension\Core\Type\CheckboxType::class, array('label' => 'Active: ','required' => false))
        ->add('permissions',  \Symfony\Bridge\Doctrine\Form\Type\EntityType::class , array(
            'class' => 'AppBundle\Entity\Permission', 
            'multiple' => true,
            'expanded' => true
        ))
        ->add('roleEntities',  \Symfony\Bridge\Doctrine\Form\Type\EntityType::class , array(
            'class' => 'AppBundle\Entity\Role', 
        ))

        ->add('save', \Symfony\Component\Form\Extension\Core\Type\SubmitType::class, array('label' => 'Save'))
        ->getForm();    

当我打开一个页面时,我得到了这个异常:

既不是属性“roleEntities”也不是方法之一 "addRoleEntity()"/"removeRoleEntity()", "setRoleEntities()", “roleEntities()”、“__set()”或“__call()”存在并具有公共访问权限 在“AppBundle\Entity\User”类中。

ps。我标记了这个“symfony2”,因为 AFAIK 2.9 和 3.0 之间没有太大区别

【问题讨论】:

  • 将您的字段命名为 roles 而不是 roleEntities
  • 但它被命名为“roles”,只是getter被命名为“getRolesEntieties” - 这是必要的,因为名为“getRoles”的函数必须返回一个字符串数组(而不是角色数组实体)来满足我实现的 AdvancedUserInterface 的期望,
  • 在表单中,您必须将其命名为 roles,如果没有名为 roleEntity 的字段,则设置为 mapped=false
  • @malcom - 我可以从你的个人资料中看到,你对 Symfony 了解很多,但我认为你还没有阅读整个问题 :( 我不能做 mapped=false,因为我确实在数据库中的用户和角色之间有关系,ManyToMany。我确实希望它被编辑(修改)。但是好的,我将表单中的字段更改为“角色”并将实体类中的属性公开,希望 Symfony 将选择它,而不是尝试在实体类中调用 getRoles 函数(因为它必须返回字符串数组而不是 $roles 属性)。现在我有这个例外:
  • 我还没有阅读整个问题,但我想通知您,您必须准确地命名表单字段,就像您在类属性中命名的那样。这样就可以正确映射。我不知道您为什么将角色用作独立实体(您以前是 drupal 开发人员吗?),而且我不知道 ORM(多年来我只使用 mongodb),所以我无法帮助您处理 ORM 映射。只是简单如果要添加表单字段,名称必须与类属性相同,否则必须设置mapped = false

标签: symfony-forms symfony


【解决方案1】:

好的,幸运的是来自#Symfony irc 的人帮助了我,那里有一些问题:

  1. 像 addRoleEntity 这样的函数应该在变量之后调用,例如添加角色

  2. 就像@malcom 提到的,在构建表单时,而不是:

    ->add('roleEntities', \Symfony\Bridge\Doctrine\Form\Type\EntityType::class , array( '类' => 'AppBundle\Entity\Role',

应该是:

->add('roles', \Symfony\Bridge\Doctrine\Form\Type\EntityType::class , array(
            'class' => 'AppBundle\Entity\Role', 
            'multiple' => true,

)

因为这是变量的命名方式。另外,由于这是 ManyToMany,我还添加了 'multiple' => true,否则它确实保存了,但错误地加载了此信息。

3.再往前走,又出现了一个新的错误:Can not read the selections from the selection list。

我将 getRoles 方法的主体更改为:

return $this->roles->toArray(); 

它奏效了。

最后一个想法是我的,不是来自 IRC,我这么说是因为我不喜欢这个解决方案。如果这是一个糟糕的解决方案,那是我的错。

【讨论】:

    猜你喜欢
    • 2012-10-02
    • 2015-07-10
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 2016-06-14
    相关资源
    最近更新 更多