Chapters
-
Course Code
Subscribe to download the code!Compatible PHP versions: >=5.3.3
Subscribe to download the code!Compatible PHP versions: >=5.3.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Sharing Data between Fixture Classes
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Sharing Data between Fixture Classes¶
Let’s update the fixtures so that each event has an owner.
We have two fixture classes: one that loads events and one that loads users.
Ordering how Fixtures are Loaded¶
Start in the LoadUsers class. Now that events depend on users, we’ll want this fixture class to be executed before the events class. To force this, implement a new interface called OrderedFixtureInterface. This requires one method called getOrder. Let’s return 10:
// src/Yoda/UserBundle/DataFixtures/ORM/LoadUsers.php
// ...
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
class LoadUsers implements FixtureInterface, ContainerAwareInterface, OrderedFixtureInterface
{
// ...
public function getOrder()
{
return 10;
}
}
Head over to LoadEvents and make the same change, except returning 20 so that the class is run second:
// src/Yoda/EventBundle/DataFixtures/ORM/LoadEvents.php
// ...
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
class LoadEvents implements FixtureInterface, OrderedFixtureInterface
{
// ...
public function getOrder()
{
return 20;
}
}
Assigning Owners in Fixtures¶
Now, we just need to get our new User objects inside LoadEvents. DoctrineFixturesBundle has a standard way of sharing data between fixtures, but a much easier way is just to query for our wayne user:
// src/Yoda/EventBundle/DataFixtures/ORM/LoadEvents.php
// ...
class LoadEvents implements FixtureInterface, OrderedFixtureInterface
{
$wayne = $manager->getRepository('UserBundle:User')
->findOneByUsernameOrEmail('wayne');
// ...
}
All we need to do now is call setOwner on both events so that it looks like wayne created them:
// src/Yoda/EventBundle/DataFixtures/ORM/LoadEvents.php
// ...
public function load(ObjectManager $manager)
{
$wayne = $manager->getRepository('UserBundle:User')
->findOneByUsernameOrEmail('wayne');
// ...
$event1->setOwner($wayne);
$event2->setOwner($wayne);
// ...
$manager->flush();
}
Ok! Reload the fixtures!
php app/console doctrine:fixtures:load
Now use app/console to check that each event has an owner:
php app/console doctrine:query:sql "SELECT * FROM yoda_event"
12 Comments
Hey Dung,
Oh boy, this looks like a PHP version compatibility problem. What version of PHP do you use? I guess that some dependencies you have are old enough for your PHP version. There're a few options - you can try to upgrade your dependencies or downgrade your PHP version. The 1st solution would be better I think, I'd recommend you to start with it and see if it helps.
Cheers!
Hi victor I upgraded from 2.2.0 to "doctrine/doctrine-fixtures-bundle": "2.4.*@dev", but still no luck. It is ok I will give up on this one since it is not worth the time. Instead I will just listen to the video and learn that way. it has been a few years since symfony 2, now I can see symfony 5 is coming :). Thank you for your help!
Hey Dung,
Ah, you would need to upgrade to 3.3.0 at least I think, I see it allows doctrine/doctrine-bundle v2.0 which in turn allow Symfony 5 packages, see here: https://packagist.org/packa... . So, yeah, this upgrade process is something that you need to do step by step. The complexity of upgrading depends on how many third-party bundles you have that uses Symfony components. The more you have - the more you nee to upgrade.
Probably some packages are still needed some time to upgrade dependencies to the latest Symfony 5 ones.
So, it's your choice, you can wait or continue to try to upgrade your dependencies earlier. Not sure how many packages you have in your application, but I heard some feedbacks about successfully upgraded applications to Symfony 5 already :)
Maybe we will have a special course about how to upgrade your application to Symfony 5. But I'm not 100% sure about it. Also, we will definitely release new courses about Symfony 5, but we won't explain how to upgrade to Symfony 5 in them.
I hope this helps!
Cheers!
Hi victor,
I tried but ran into error again
Fatal error: Out of memory (allocated 1686110208) (tried to allocate 4096 bytes) in phar...
I do not have the need for Symfony2 to work so I will just watch and learn the video and apply in my Symfony4.
Thank you for your time!
Hey Dung,
Oh, yeah, looks like you need to turn off memory limit for "composer update" command, see Composer's docs about how to do it and choose whatever option is better for you: https://getcomposer.org/doc...
Also, yeah, I noticed that you're looking at Symfony 2 screencasts :) Actually, every time when the new major version of Symfony is released - we record a new screencasts about it. Basically, concepts are the same, but code might be a bit different because some classes/methods might be renamed, new features might be added, etc. So, what I'm trying to say is that you can just go with our Symfony 4 tutorials instead, look into Symfony 4 track: https://symfonycasts.com/tr... - those are the latest screencasts about Symfony :) Soon, we will start releasing Symfony 5 tutorials that just will replace our Symfony 4 ones. So, basically, if you watch the latest course about Symfony and skip old ones - you won't lose a big value. Yes, you might find something interesting in old tutorials, but their value would be pretty little in case you've watched new ones. So, in case you don't have a Symfony 2 project that you would like to deal with - I'd recommend you to start with the latest Symfony tutorials we have - Symfony 4 track :)
I hope this helps!
Cheers!
Hello victor,
Those are good links you gave. Yes, my project is Symfony 4, I will just focus on those Symfony 4 tutorials.
Thank you for your support!
Shouldn't the call to setOwner() have to occur before the persist()? If not, why?
Hey Michael!
That wasn't on purpose, but it makes for a great question :). The answer is: it doesn't matter (but it does need to be before flush). When you call persist(), it basically tells Doctrine: "Hey, be aware of this object. Later, if/when someone calls flush(), you should check out this object and save it to the database". Using persist doesn't put a "snapshot" of it in Doctrine at that time, it more just lets Doctrine know that it should be saved, once the time comes.
Cheers!
Thanks! That's a great explanation.
in Symfony 2.8 I had to add
@ORM\JoinColumn(onDelete="SET NULL")
To the $owner variable.
Before a SQL error appeared:
[Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException]
An exception occurred while executing 'DELETE FROM yoda_user':
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or upda
te a parent row: a foreign key constraint fails (`symfony`.`yoda_event`, CO
NSTRAINT `FK_133826D97E3C61F9` FOREIGN KEY (`owner_id`) REFERENCES `yoda_us
er` (`id`))
Just in case someone else comes across this problem...
Yo Max!
This is a good find, and a pretty common - sometimes annoying "feature" in Doctrine. By default, all relationships have ON DELETE RESTRICT in the database: if you try to delete a User, but it is the "owner" of an Event... then you'll get this error. So, you have the right fix (well, that or "CASCADE"), as long as it fits your situation (I'd say, in this case, as long as knowing the $owner of an Event isn't mission critical, then this is cool. Otherwise, you might want CASCADE).
Cheers!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=5.3.3",
"symfony/symfony": "~2.4", // v2.4.2
"doctrine/orm": "~2.2,>=2.2.3", // v2.4.2
"doctrine/doctrine-bundle": "~1.2", // v1.2.0
"twig/extensions": "~1.0", // v1.0.1
"symfony/assetic-bundle": "~2.3", // v2.3.0
"symfony/swiftmailer-bundle": "~2.3", // v2.3.5
"symfony/monolog-bundle": "~2.4", // v2.5.0
"sensio/distribution-bundle": "~2.3", // v2.3.4
"sensio/framework-extra-bundle": "~3.0", // v3.0.0
"sensio/generator-bundle": "~2.3", // v2.3.4
"incenteev/composer-parameter-handler": "~2.0", // v2.1.0
"doctrine/doctrine-fixtures-bundle": "~2.2.0", // v2.2.0
"ircmaxell/password-compat": "~1.0.3", // 1.0.3
"phpunit/phpunit": "~4.1", // 4.1.0
"stof/doctrine-extensions-bundle": "~1.1.0" // v1.1.0
}
}
Hi Symfonycasts,
I thought the error is simple easy quick fix but I can not find the solution for it, can you please help identify this error for this tutorial?
Thank you!