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或其他什么东西出错了,关于这个的任何建议呢?
基本上只是基于快速查看文档的猜测,但我怀疑问题可能是在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)