Настройка параметра в виде массива в генераторе приборов Nelmio Alice

Я спрашиваю, возможно ли передать массив в качестве значения для некоторых элементов? Например, в моем случае я пытаюсь установить роли для 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] Catchable Fatal Error: Аргумент 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

Любой совет по этому поводу?

Обновить ответ

Используя первый подход с простым массивом в файле 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] Catchable Fatal Error: Аргумент 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 или что-то еще не так, есть ли какие-то советы по поводу этого тоже?

2 ответа

Решение

По сути, это всего лишь предположение, основанное на быстром взгляде на документы, но я подозреваю, что проблема может заключаться в том, что в 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'];
}

YAML

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

Последний запрос: действительно ли вы хотите, чтобы Алиса назначала все эти роли пользователю в 35% случаев? Если нет, и на самом деле вы хотите некоторый выбор на основе вероятности одного из них в каждом пользователе, то я предполагаю, что вам все еще нужен пользовательский метод, но поместите туда логику выбора вместо YAML.

РЕДАКТИРОВАТЬ

Ах, звучит так, как будто вы хотите случайные одиночные роли для каждого экземпляра теста, и в этом случае вам понадобится специальный код, например, такой:

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

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

По словам Алисы, похоже, что вы можете вставить это прямо в 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 расскажут вам, как включить отдельного провайдера (как описано выше)

services.yml

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


Это предложение не работает, сохраняя для потомков, но переместилось вниз!

Я подумал, что, возможно, вы можете сделать это, определив массив отдельно вверху, а затем сослаться на него, используя объекты значений Алисы, но, поскольку массив не является обычным объектом, я не могу понять, как его создать. Вы хотели бы что-то вроде этого:

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*

Попробуй это

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

randomElements арг:
1-массив 'Массив, чтобы взять элементы из. По умолчанию a-f '.
2 - целое число "Количество элементов, которые нужно взять".
3 - логическое значение "Разрешить выбор элементов несколько раз". По умолчанию false.

Он вернет массив.

Проблема, которую я считаю, заключается в том, что вам нужно установить массив ролей, чтобы вы не могли просто вернуть одну роль. Либо сделать это в строке:

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*

Другая проблема может заключаться в том, что когда вы передаете массив чему-либо, он может распаковать его как список аргументов. Попробуй пройти [ ['Foo'] ] то есть массив как первый аргумент другого массива. В любом случае, как только вы это выясните, я думаю, вам следует отправить запрос на получение документации или подать вопрос хотя бы потому, что это, вероятно, не должно быть таким сложным.

Другие вопросы по тегам