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

Rey*_*rPM 7 php fixtures symfony

我问是否可以将数组作为某些元素的值传递?例如,在我的情况下,我正在尝试为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*
Run Code Online (Sandbox Code Playgroud)

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

[Symfony的\元器件\调试\异常\ ContextErrorException]捕致命错误:传递给FOS\UserBundle \模型\用户:: setRoles(参数1)必须是类型阵列,给定的字符串,称为在/ var的/ WWW/HTML /在线路483供应商/ nelmio /爱丽丝/ SRC/Nelmio /爱丽丝/装载机/ Base.php和/var/www/html/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Model/User.php线530限定

对此有何建议?

更新答案

在YAML文件中使用第一种方法使用plain数组:

在做出一些改变之后@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*
Run Code Online (Sandbox Code Playgroud)

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

但是每当我尝试通过调用来执行该集合时:

h4cc_alice_fixtures:load:sets ./src/CommonBundle/DataFixtures/TananeSet.php
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

[ErrorException]捕致命错误:传递给学说\共同\类别\ ArrayCollection的:: __构建体(参数1)必须是类型的阵列,对象给出的,称为在/ var/www/html等/供应商/教义/ ORM/LIB /教义/ ORM/UnitOfWork.phpø
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;

}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个错误?我应该作为参数传递什么groups

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

按照@frumious的另一个建议,我定义了一个服务如下:

services:
    roles.faker.provider:
        class: CommonBundle\Tools\RolesFakerProvider
        tags:
            -  { name: h4cc_alice_fixtures.provider }
Run Code Online (Sandbox Code Playgroud)

这是方法:

namespace CommonBundle\Tools;

class RolesFakerProvider {

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

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

}
Run Code Online (Sandbox Code Playgroud)

然后我做了这个改变:

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*
Run Code Online (Sandbox Code Playgroud)

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

[Symfony的\元器件\调试\异常\ ContextErrorException]捕致命错误:传递给FOS\UserBundle \模型\用户:: setRoles(参数1)必须是类型阵列,给定的字符串,称为在/ var的/ WWW/HTML /供应商/ nelmio /爱丽丝/ SRC/Nelmio /爱丽丝/装载机/ Base.php在/var/www/html/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Model/User.php线530线483和定义过

这让我觉得这个功能没有回归array或其他什么东西出错了,关于这个的任何建议呢?

fru*_*ous 6

基本上只是基于快速查看文档的猜测,但我怀疑问题可能是在roles: 35%? [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO]后面roles:被解释为单个字符串,因为它不像[正常的YAML数组所需的那样开始.

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

一个(未经证实)选项:使用自定义Faker方法:

骗子

public function roles()
{
    return = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO'];
}
Run Code Online (Sandbox Code Playgroud)

YAML

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

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

编辑

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

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

    return $names[array_rand($names)];
}
Run Code Online (Sandbox Code Playgroud)

爱丽丝说,看起来你可以像以下一样直接坚持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*
Run Code Online (Sandbox Code Playgroud)

或者AliceFixturesBundle文档告诉您如何包含单独的Provider(如上所述)

services.yml

services:
    your.faker.provider:
        class: YourProviderClass
        tags:
            -  { name: h4cc_alice_fixtures.provider }
Run Code Online (Sandbox Code Playgroud)


这个建议不起作用,为后代保留,但从底部移动!

我想也许你可以做到这一点,分别在顶部定义数组,然后使用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*
Run Code Online (Sandbox Code Playgroud)