How to create circular references with a fixture?
Let's consider this model:
A:
columns:
b_id:
type: int
notnull: false
relations:
b: B
local: b_id
foreignAlias: as
B:
columns:
a_id:
type: int
notnull: true
relations:
a: A
foreignAlias: bs
Notice that b_id can be null. Is it possible to create with one or several fixtures an A object with a relation to a B object that references back the a object himself, and if yes, how? More generic question, is it possible to:
- create an A
- create a B
- Update the A
Or more simply, is it possible to update an object with a fixture? After Tom's answer I tried
greg@liche:~/project/symfony$ ./symfony doctrine:data-load update --append
>> doctrine Loading d开发者_JAVA技巧ata fixtures from "update"
>> doctrine Data was successfully loaded
The update directory contains a fixture which looks like this:
A:
a_fixture_identifier:
b: b_fixture identifier
after loading this fixture:
A:
a_fixture_identifier:
B:
b_fixture_identifier:
a: a_fixture_identifier
It says the update fixture file loaded successfully, but it does not seem to update anything. I can't understand how the second fixture file would know about the fixture identifiers declared in the initial file... What can I try?
The fixtures are meant for adding some data into your tables, so yes, it's all about updating objects with fixture data.
You can add this data anyhow you like as long as you don't violate the constraints that you've specified in your schema. In the case of relations, the referenced value(s) must come before the referencing value(s) or otherwise the relation cannot be declared.
This is sometimes the case when uploading complex fixture data from a single fixtures file. What I've noticed that to get around it, load one set of fixtures, then remove that file and load another set of fixtures. In other words, even if the relationships exist in a single fixture file correctly, symfony/doctrine seems unable (at least in some cases) to load them all at once. Think in terms of "sets of data" rather than a complete database.
I can't think of a case where a fixture file for one table would update another table. If you need this, I'd suggest writing a little data load script using Doctrine models and their methods.
UPDATE:
Misunderstood the question originally: I dont think fixtures can be used to actually update an existing record. The "append" option is about appending more data to a table that already contains data. I think it's separate because generally fixtures would only be used on tables that have just been built and that you want to test - not to actually perform update operations on existing data. For this, I would suggest writing a separate script.
UPDATE:
greg0ire: I used this solution, and it works.
First, I connect the command.post_command
event to my script:
$this->dispatcher->connect('command.post_command',
array('MmcCmsDoctrineDataLoadTaskListener', 'fixCircularReferences'));
Then, in my script I check that the task is 'data-load', and make the missing links to close the circle.
public static function fixCircularReferences(sfEvent $event)
{
/* @var $task sfTask */
$task = $event->getSubject();
if ($task->getName() == 'data-load')
{
// make the links here
}
}
WARNING : Do not attempt to create the circular in the fixtures, but deliberately let one relation empty, otherwise you will encounter strange problems.
精彩评论