我正在尝试为我的新Symfony 4项目创建一组固定装置。我面临一个与我的实体之间的某些关系有关的问题。
在这里,您可以找到相关的实体:
用户
class User implements UserInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=180, unique=true)
*/
private $username;
/**
* @var array
*
* @ORM\Column(type="json")
*/
private $roles = [];
/**
* @var string The hashed password
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $firstname;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $insertion;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $lastname;
/**
* @ORM\Column(type="string", length=255)
*/
private $email;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\UserGroup", inversedBy="users")
* @ORM\JoinColumn(nullable=false)
*/
private $userGroup;
}
UserGroup
class UserGroup
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $title;
/**
* @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="userGroup")
*/
private $users;
}
我决定使用某些方法创建BaseFixture类。我在Symfonycast上发现了这个想法:https://symfonycasts.com/screencast/doctrine-relations/awesome-random-fixtures。
这里是:
/**
* Class BaseFixture
* @package App\DataFixtures
*/
abstract class BaseFixture extends Fixture
{
/** @var ObjectManager */
private $manager;
/** @var Generator */
protected $faker;
/**
* @var array
*/
private $referencesIndex = [];
/**
* @param ObjectManager $manager
* @return mixed
*/
abstract protected function loadData(ObjectManager $manager);
/**
* @param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
$this->manager = $manager;
$this->faker = Factory::create();
$this->loadData($manager);
}
/**
* @param string $className
* @param int $count
* @param callable $factory
*/
protected function createMany(string $className, int $count, callable $factory)
{
for ($i = 0; $i < $count; $i++) {
$entity = new $className();
$factory($entity, $i);
$this->manager->persist($entity);
$this->addReference($className . '_' . $i, $entity);
}
}
/**
* @param string $className
* @return object
* @throws Exception
*/
protected function getRandomReference(string $className)
{
if (!isset($this->referencesIndex[$className])) {
$this->referencesIndex[$className] = [];
foreach ($this->referenceRepository->getReferences() as $key => $ref) {
if (strpos($key, $className.'_') === 0) {
$this->referencesIndex[$className][] = $key;
}
}
}
if (empty($this->referencesIndex[$className])) {
throw new Exception(sprintf('Cannot find any references for class "%s"', $className));
}
$randomReferenceKey = $this->faker->randomElement($this->referencesIndex[$className]);
return $this->getReference($randomReferenceKey);
}
/**
* @param string $className
* @param int $count
* @return array
* @throws Exception
*/
protected function getRandomReferences(string $className, int $count)
{
$references = [];
while (count($references) < $count) {
$references[] = $this->getRandomReference($className);
}
return $references;
}
}
然后,我有2个装置:
/**
* Class UserGroupFixtures
* @package App\DataFixtures
*/
class UserGroupFixtures extends Fixture
{
/**
* @param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
/** @var UserGroup $adminUserGroup */
$adminUserGroup = new UserGroup();
$adminUserGroup->setTitle('admin');
$manager->persist($adminUserGroup);
/** @var UserGroup $adminUserGroup */
$userUserGroup = new UserGroup();
$userUserGroup->setTitle('user');
$manager->persist($userUserGroup);
/** @var UserGroup $adminUserGroup */
$viewerUserGroup = new UserGroup();
$viewerUserGroup->setTitle('viewer');
$manager->persist($viewerUserGroup);
$manager->flush();
}
}
和用户装置:
class UserFixtures extends BaseFixture implements DependentFixtureInterface
{
/**
* @var array
*/
private static $userRoles = [
["ROLE_ADMIN"],
["ROLE_USER"]
];
/**
* @var array
*/
private static $userInsertion = [
'van',
'de',
''
];
private $passwordEncoder;
/**
* UserFixtures constructor.
* @param UserPasswordEncoderInterface $passwordEncoder
*/
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
$this->passwordEncoder = $passwordEncoder;
}
/**
* @param ObjectManager $manager
*/
protected function loadData(ObjectManager $manager)
{
$this->createMany(User::class, 10, function(User $user) use ($manager) {
$user->setUsername($this->faker->userName);
$user->setRoles($this->faker->randomElement(self::$userRoles));
$user->setPassword($this->passwordEncoder->encodePassword($user, 'ACTIVO'));
$user->setFirstname($this->faker->firstName);
$user->setLastname($this->faker->lastName);
$user->setInsertion($this->faker->randomElement(self::$userInsertion));
$user->setEmail($this->faker->email);
$user->setDateCreated($this->faker->dateTime);
$user->setDateUpdate($this->faker->dateTime);
$user->setUnsubscribed($this->faker->boolean(15));
$user->setDateUnsubscribed($this->faker->dateTime);
$user->setUserGroup($this->getRandomReference(UserGroup::class));
});
$manager->flush();
}
/**
* @return array|string
*/
public function getDependencies()
{
return [UserGroupFixtures::class];
}
}
如您所见,我使用getDependencies()函数是因为UserGroup的固定装置必须在User之前存在。
[当我启动命令以加载灯具时,UserGroupFixtures在UserGroup之前被调用,但是...。我在BaseFixture文件中的此行遇到错误:
if (empty($this->referencesIndex[$className])) {
throw new Exception(sprintf('Cannot find any references for class "%s"', $className));
}
一些帮助将不胜感激,因为很难调试固定装置;)
正如最初评论的那样,问题似乎是您没有将UserGroup实例存储在第一个装置的引用中。您可以尝试将UserGroupFixtures
类更新为以下内容:
/**
* Class UserGroupFixtures
* @package App\DataFixtures
*/
class UserGroupFixtures extends Fixture
{
/**
* @param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
/** @var UserGroup $adminUserGroup */
$adminUserGroup = new UserGroup();
$adminUserGroup->setTitle('admin');
$manager->persist($adminUserGroup);
$this->addReference(UserGroup::class . '_1', $adminUserGroup);
/** @var UserGroup $adminUserGroup */
$userUserGroup = new UserGroup();
$userUserGroup->setTitle('user');
$manager->persist($userUserGroup);
$this->addReference(UserGroup::class . '_2', $userUserGroup);
/** @var UserGroup $adminUserGroup */
$viewerUserGroup = new UserGroup();
$viewerUserGroup->setTitle('viewer');
$manager->persist($viewerUserGroup);
$this->addReference(UserGroup::class . '_3', $viewerUserGroup);
$manager->flush();
}
}