在Nelmio Alice夹具生成器中将参数设置为数组

时间:2014-09-26 01:51:16

标签: php symfony fixtures

我问是否可以将数组作为某些元素的值传递?例如,在我的情况下,我试图为FOSUserBundle User实体设置角色,该实体将roles作为值数组而不是普通值。我的夹具中有这个:

UserBundle\Entity\User:
    User0:
        username: admin
        email: admin@local.com
        enabled: 1
        plainPassword: admin
        roles: [ROLE_ADMIN]
        groups: @Group0

    User{1..10}:
        username: <firstNameMale>
        email: <companyEmail>
        enabled: <boolean(35)>
        plainPassword: <lexify>
        roles: 35%? [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO]
        groups: @Group*

但是它没有用,而且我收到了这个错误:

  

[Symfony的\元器件\调试\异常\ ContextErrorException]   可捕获的致命错误:传递给FOS \ UserBundle \ Model \ User :: setRoles()的参数1必须是   类型数组,给定的字符串,调用   /var/www/html/vendor/nelmio/alice/src/Nelmio/Alice/Loader/Base.php在第483行并定义于   /var/www/html/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Model/User.php line 530

有关此问题的任何建议吗?

更新回答

在YAML文件中使用普通数组的第一种方法:

在做了一些更改之后@frumious建议夹具现在有这样的内容:

UserBundle\Entity\User:
    User0:
        username: admin
        email: admin@local.com
        enabled: 1
        plainPassword: admin
        roles: [ROLE_ADMIN]
        groups: @Group0

    User{1..10}:
        username: <firstNameMale>
        email: <companyEmail>
        enabled: <boolean(35)>
        plainPassword: <lexify>
        roles: [ROLE_PROFILE_ONE, ROLE_PROFILE_TWO]
        groups: @Group*

通过这种方式,我将为每个测试用户分配两个角色,但是我在尝试获取Faker应放置的位置以及在其中写入的代码时遇到了一些问题。

但是每当我尝试通过调用

来执行该集合时
h4cc_alice_fixtures:load:sets ./src/CommonBundle/DataFixtures/TananeSet.php

我收到了这个错误:

  

[ErrorException] Catchable Fatal Error:参数1传递给   Doctrine \ Common \ Collections \ ArrayCollection :: __ construct()必须是   类型数组,给定对象,调用   /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php o
  n行555并定义于   /var/www/html/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php   第47行

这让我觉得这里的问题与$groups实体中的User变量有关。这是该实体的一段代码:

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
 * @ORM\Entity(repositoryClass="UserBundle\Entity\Repository\UserRepository")
 */
class User extends BaseUser {
    /**
     * Hook timestampable behavior
     * updates createdAt, updatedAt fields
     */
    use TimestampableEntity;

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="Group")
     * @ORM\JoinTable(name="fos_user_user_group",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     * )
     */
    protected $groups;

    /**
     * @ORM\Column(name="deletedAt", type="datetime", nullable=true)
     */
    protected $deletedAt;

}

我如何修复该错误?我应该作为groups的参数传递什么?

使用第二种方法:定义服务

根据@frumious的其他建议,我将服务定义如下:

services:
    roles.faker.provider:
        class: CommonBundle\Tools\RolesFakerProvider
        tags:
            -  { name: h4cc_alice_fixtures.provider }

这是方法:

namespace CommonBundle\Tools;

class RolesFakerProvider {

    public function randomRoles()
    {
        $names = ['ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO'];

        return [$names[array_rand($names)]];
    }

}

然后我做了这个改变:

UserBundle\Entity\User:
    User0:
        username: admin
        email: admin@local.com
        enabled: 1
        plainPassword: admin
        roles: [ROLE_ADMIN]
        groups: @Group0

    User{1..10}:
        username: <firstNameMale>
        email: <companyEmail>
        enabled: <boolean(35)>
        plainPassword: <lexify>
        # BEFORE
        #roles: [ROLE_PROFILE_ONE, ROLE_PROFILE_TWO]
        # AFTER
        roles: <randomRoles>
        groups: @Group*

而这一个正在返回此错误:

  

[Symfony \ Component \ Debug \ Exception \ ContextErrorException]可捕获   致命错误:参数1传递给   FOS \ UserBundle \ Model \ User :: setRoles()必须是类型数组,   给出的字符串,调用   /var/www/html/vendor/nelmio/alice/src/Nelmio/Alice/Loader/Base.php   在第483行并定义于   /var/www/html/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Model/User.php   第530行

这让我觉得这个函数不会返回array或其他什么东西出错了,对此也有任何建议吗?

3 个答案:

答案 0 :(得分:6)

基本上只是基于快速查看文档的猜测,但我怀疑问题可能是roles: 35%? [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] roles:被解释为单个字符串后的位,因为它没有&# 39; t以[开头,因为正常的YAML数组需要。

至于解决方案,我怀疑你不能像YAML一样直接做到这一点。

一个(未经证实)选项:使用custom Faker method

法克尔

public function roles()
{
    return = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO'];
}

YAML

User{1..10}:
    username: <firstNameMale>
    email: <companyEmail>
    enabled: <boolean(35)>
    plainPassword: <lexify>
    roles: 35%? <roles()>
    groups: @Group*

最终查询:您真的希望Alice在35%的时间内将所有这些角色分配给用户吗?如果没有,实际上你想要在每个用户中选择一个基于概率的选择,那么我认为你需要的仍然是一个自定义方法,但是将选择逻辑放在那里而不是在YAML中。

修改

啊,听起来你想为每个测试实例提供随机单个角色,在这种情况下你需要这样的自定义代码:

public function randomRole()
{
    $names = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO'];

    return $names[array_rand($names)];
}

根据Alice,看起来你可以直接在YAML中坚持这样:

User{1..10}:
    username: <firstNameMale>
    email: <companyEmail>
    enabled: <boolean(35)>
    plainPassword: <lexify>
    roles: <?php $names = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO']; echo $names[array_rand($names)]; ?>
    groups: @Group*

AliceFixturesBundle docs告诉您如何包含单独的提供商(如上所述)

services.yml

services:
    your.faker.provider:
        class: YourProviderClass
        tags:
            -  { name: h4cc_alice_fixtures.provider }

<小时/> 这个建议不起作用,为子孙后代保留下来但是从底部开始了!

我想也许你可以这样做,分别在顶部定义数组,然后使用Alice Value Objects引用它,但由于数组不是普通对象,我无法看到如何实例化它。你想要这样的东西:

Array:
    Array0: [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO]

UserBundle\Entity\User:
    User0:
        username: admin
        email: admin@local.com
        enabled: 1
        plainPassword: admin
        roles: [ROLE_ADMIN]
        groups: @Group0

    User{1..10}:
        username: <firstNameMale>
        email: <companyEmail>
        enabled: <boolean(35)>
        plainPassword: <lexify>
        roles: 35%? @Array0
        groups: @Group*

答案 1 :(得分:1)

我认为问题是你需要设置一组角色,所以你不能只返回一个角色。要么在线执行此操作:

User{1..10}:
    username: <firstNameMale>
    email: <companyEmail>
    enabled: <boolean(35)>
    plainPassword: <lexify>
    roles: <?php $names = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO']; echo '['.$names[array_rand($names)].']'; ?>
    groups: @Group*

另一个问题可能是,当你给一个数组时,它可能会将它解压缩为arg列表。尝试将其传递给[ ['Foo'] ],即将数组作为另一个数组的第一个arg。无论哪种方式,一旦你弄明白我认为你应该发送文件的拉取请求或至少提出问题,因为这可能不是那么复杂。

答案 2 :(得分:0)

尝试这个

roles: <randomElements(['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO'], 2)>

randomElements参数:
1- array'从中获取元素的数组。默认为a-f'。
2-整数“要采用的元素数”。
3- boolean'允许元素被选择多次。默认为false”。

它将返回数组。