首页 文章

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

提问于
浏览
7

我'm asking if it'可以传递数组作为某些元素的值吗?例如,在我的情况下,我正在尝试为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 \ Component \ Debug \ Exception \ ContextErrorException]可捕获致命错误:传递给FOS \ UserBundle \ Model \ User :: setRoles()的参数1必须是类型数组,字符串给定,在/ var / www / html中调用第483行的/vendor/nelmio/alice/src/Nelmio/Alice/Loader/Base.php,并在/var/www/html/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Model/User.php第530行中定义

对此有何建议?

更新答案

Using first approach with plain array in YAML file:

在做出一些改变之后@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:传递给Doctrine \ Common \ Collections \ ArrayCollection :: __ construct()的参数1必须是类型数组,给定对象,在/ var / www / html / vendor / doctrine / orm / lib中调用第555行/Doctrine/ORM/UnitOfWork.php,在/var/www/html/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php第47行中定义

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

/**
 * @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 的参数传递什么?

Using second approach: defining a service

按照@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]可捕获致命错误:传递给FOS \ UserBundle \ Model \ User :: setRoles()的参数1必须是类型数组,字符串给定,在/ var / www / html中调用第483行的/vendor/nelmio/alice/src/Nelmio/Alice/Loader/Base.php,并在/var/www/html/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Model/User.php一行中定义530

这让我觉得这个函数没有返回 array 或其他什么东西出错了,围绕这个的任何建议呢?

3 回答

  • 0

    基本上只是基于快速查看文档的猜测,但我怀疑问题可能是在 roles: 35%? [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] 之后 roles: 被解释为单个字符串,因为它不是以 [ 开头,因为正常的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引用它,但由于数组不是普通对象,我可以't see how to instantiate it. You' d想要这样的东西:

    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

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

    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 . 无论哪种方式,一旦你弄明白我认为你应该发送文件的拉取请求或至少提出问题,因为这可能不应该这么复杂 .

  • 6

    试试这个吧

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

    randomElements args:
    1- array 'Array to take elements from. Defaults to a-f' .
    2-整数'Number of elements to take' . 3-布尔'Allow elements to be picked several times. Defaults to false' .

    它将返回数组 .

相关问题