This project is no longer maintained and has been archived. |
Data Fixtures
Data fixtures are meant for loading small sets of test data through your models to populate your database with data to test against. The data fixtures are often used side by side with some kind of unit/functional testing suite.
Importing
Importing data fixtures is just as easy as dumping. You can use the
loadData()
function:
$ Doctrine_Core::loadData('/path/to/data.yml');
You can either specify an individual yml file like we have done above, or you can specify an entire directory:
$ Doctrine_Core::loadData('/path/to/directory');
If you want to append the imported data to the already existing data
then you need to use the second argument of the loadData()
function.
If you don't specify the second argument as true then the data will be
purged before importing.
Here is how you can append instead of purging:
$ Doctrine_Core::loadData('/path/to/data.yml', true);
Dumping
You can dump data to fixtures file in many different formats to help you get started with writing your data fixtures. You can dump your data fixtures to one big YAML file like the following:
$ Doctrine_Core::dumpData('/path/to/data.yml');
Or you can optionally dump all data to individual files. One YAML file per model like the following:
$ Doctrine_Core::dumpData('/path/to/directory', true);
Implement
Now that we know a little about data fixtures lets implement them in to our test environment we created and have been using through the previous chapters so that we can test the example fixtures used in the next sections.
First create a directory in your doctrine_test
directory named
fixtures
and create a file named data.yml
inside:
$ mkdir fixtures
$ touch fixtures/data.yml
Now we need to just modify our generate.php
script to include the
code for loading the data fixtures. Add the following code to the bottom
of generate.php
:
// generate.php
// ...
Doctrine_Core::loadData('fixtures');
Writing
You can write your fixtures files manually and load them in to your
applications. Below is a sample data.yml
fixtures file. You can also
split your data fixtures file up in to multiple files. Doctrine will
read all fixtures files and parse them, then load all data.
For the next several examples we will use the following models:
// models/Resouce.php
class Resource extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 255);
$this->hasColumn('resource_type_id', 'integer');
}
public function setUp()
{
$this->hasOne('ResourceType as Type', array(
'local' => 'resource_type_id',
'foreign' => 'id'
)
);
$this->hasMany('Tag as Tags', array(
'local' => 'resource_id',
'foreign' => 'tag_id',
'refClass' => 'ResourceTag'
)
);
}
}
// models/ResourceType.php
class ResourceType extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 255);
}
public function setUp()
{
$this->hasMany('Resource as Resouces', array(
'local' => 'id',
'foreign' => 'resource_type_id'
)
);
}
}
// models/Tag.php
class Tag extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 255);
}
public function setUp()
{
$this->hasMany('Resource as Resources', array(
'local' => 'tag_id',
'foreign' => 'resource_id',
'refClass' => 'ResourceTag'
)
);
}
}
// models/ResourceTag.php
class ResourceTag extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('resource_id', 'integer');
$this->hasColumn('tag_id', 'integer');
}
}
// models/Category.php
class BaseCategory extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 255, array(
'type' => 'string', 'length' => '255'
)
);
}
public function setUp()
{
$this->actAs('NestedSet');
}
}
class BaseArticle extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('title', 'string', 255, array(
'type' => 'string', 'length' => '255'
)
);
$this->hasColumn('body', 'clob', null, array(
'type' => 'clob'
)
);
}
public function setUp()
{
$this->actAs('I18n', array('fields' => array('title', 'body')));
}
}
Here is the same example in YAML format. You can read more about YAML in the YAML Schema Files chapter:
1 ---
# schema.yml
Resource:
columns:
name: string(255)
resource_type_id: integer
relations:
Type:
class: ResourceType
foreignAlias: Resources
Tags:
class: Tag
refClass: ResourceTag
foreignAlias: Resources
ResourceType:
columns:
name: string(255)
Tag:
columns:
name: string(255)
ResourceTag:
columns:
resource_id: integer
tag_id: integer
Category:
actAs: [NestedSet]
columns:
name: string(255)
Article:
actAs:
I18n:
fields: [title, body]
columns:
title: string(255)
body: clob
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
All row keys across all YAML data fixtures must be unique. For example below tutorial, doctrine, help, cheat are all unique. |
1 ---
# fixtures/data.yml
Resource:
Resource_1:
name: Doctrine Video Tutorial
Type: Video
Tags: [tutorial, doctrine, help]
Resource_2:
name: Doctrine Cheat Sheet
Type: Image
Tags: [tutorial, cheat, help]
ResourceType:
Video:
name: Video
Image:
name: Image
Tag:
tutorial:
name: tutorial
doctrine:
name: doctrine
help:
name: help
cheat:
name: cheat
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
You could optionally specify the Resources each tag is related to instead of specifying the Tags a Resource has.
Fixtures For Nested Sets
Writing a fixtures file for a nested set tree is slightly different from writing regular fixtures files. The structure of the tree is defined like the following:
When writing data fixtures for the NestedSet you must either
specify at least a |
Or simply specifying the children keyword will make the data fixtures importing using the NestedSet api.
If you don't use one of the above methods then it is up to you to manually specify the lft, rgt and level values for your nested set records.
Fixtures For I18n
The fixtures for the I18n
aren't anything custom since the I18n
really is just a normal set of relationships that are built on the fly
dynamically:
Conclusion
By now we should be able to write and load our own data fixtures in our application. So, now we will move on to learning about the underlying Database Abstraction Layer in Doctrine. This layer is what makes all the previously discussed functionality possible. You can use this layer standalone apart from the ORM. In the next chapter we'll explain how you can use the DBAL by itself.