在DoctrineFixturesBundle中,如果我想按指定的顺序执行fixtures,我必须在任何fixture类方法中创建如下:
public function getOrder()
{
return 2;
}
指定订单并不舒服。
在Laravel Framework中,我可以这样做:
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call('PositionsSeeder');
$this->call('UsersSeeder');
$this->call('PostsSeeder');
}
}
我的问题是:我可以在symfony中这样做吗?
我看到一个解决方案。我可以使用以下代码制作BaseFixture:
class LoadBrandData extends AbstractFixture
{
public function load(ObjectManager $manager)
{
(new LoadPositionsData())->load(manager);
(new LoadUsersData())->load(manager);
(new LoadPostsData())->load(manager);
}
}
但也许我可以做得更好。我可以吗?
即使你不喜欢它,实现这一目标的最好方法是通过getOrder()
方法。
话虽如此,您可以使用至少两个技巧以其他方式设置订单:
您可以使用Doctrine DependentFixtureInterface;请查看以下示例:
namespace MyDataFixtures;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
class MyFixture extends AbstractFixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager)
{}
public function getDependencies()
{
return array('MyDataFixtures\MyOtherFixture'); // fixture classes fixture is dependent on
}
}
class MyOtherFixture extends AbstractFixture
{
public function load(ObjectManager $manager)
{}
}
这就是我的工作。
创建一个将存储加载顺序的类。
<?php
namespace AppBundle\DataFixtures;
use AppBundle\DataFixtures\ORM\LoadClientData;
use AppBundle\DataFixtures\ORM\LoadRoleData;
use AppBundle\DataFixtures\ORM\LoadUserData;
class Order
{
const FIXTURES = [
LoadRoleData::class,
LoadUserData::class,
LoadClientData::class,
];
}
然后,在您的抽象fixture类(将由所有其他fixture继承的类)中,创建以下方法:
/**
* @return int
* @throws \Exception
*/
public function getOrder()
{
$order = array_search(get_called_class(), Order::FIXTURES);
if ($order === false) {
throw new \Exception('Seems like you forgot to put things in Order');
}
return $order;
}
你永远不应该直接从灯具本身调用getOrder
方法。