How do I set up fixtures with relationships in Yii? For example, with posts can have comments, how do I refer to the post id in a fixture for creating comments?
Post fixture:
return array(
'post1'=>array(
'title'=>'My title',
'body'=>'My text',
),
...
Comment fixture:
return array(
'comment1'=>array(
'text'=>'Comment text...',
'post_id'=> ???
),
The ActiveRecord class in Yii provides an object oriented interface (aka ORM) for accessing database stored data. Similar structures can be found in most modern frameworks like Laravel, CodeIgniter, Smyfony and Ruby.
Active Record automatically maintains the list of dirty attributes. It does so by maintaining an older version of the attribute values and comparing them with the latest one. You can call yii\db\ActiveRecord::getDirtyAttributes() to get the attributes that are currently dirty.
Applications are objects that govern the overall structure and lifecycle of Yii application systems. Each Yii application system contains a single application object which is created in the entry script and is globally accessible through the expression \Yii::$app .
I don't know whether there is a dynamic way to do that, but the following should work:
Post fixture:
return array(
'post1' => array(
'id' => 1
'title' => 'My title',
'body' => 'My text',
),
Comment fixture:
return array(
'comment1' => array(
'text' => 'Comment text...',
'post_id' => 1
),
As far as I've worked out, you can use init scripts instead of classical fixtures. The Yii documentation reads:
It is also possible that we do not like the default way of resetting a table, i.e., truncating it and inserting it with the fixture data. If this is the case, we can write an initialization script for the specific fixture file. The script must be named as the table name suffixed with .init.php. For example, the initialization script for the Post table would be Post.init.php. When CDbFixtureManager sees this script, it will execute this script instead of using the default way to reset the table.
So in your case, instead of having protected/tests/fixtures/Comment.php
, you would have protected/tests/fixtures/Comment.init.php
which does this:
// the $this variable refers to the CBdFixtureManager instance
$this->truncateTable($tableName);
$post = $this->getRecord('Post','post1'); // get dependent fixture
// define new fixture
$commentAttributes = array(
'text' => 'Comment text...',
'post_id' => $post->id
);
$comment = new Comment;
$comment->setAttributes($commentAttributes);
if(!$comment->save()) throw new CException('Unable to save fixture');
// add new row primary key
$pk = Comment::model()->getTableSchema()->primaryKey;
if(is_string($pk))
$commentAttributes[$pk] = $comment->$pk;
elseif(is_array($pk))
foreach($pk as $key)
$commentAttributes[$key] = $comment->$key;
$this->_rows['Comment']['comment1'] = $commentAttributes;
$this->_records['Comment']['comment1'] = 'Comment';
Although I realize it's a very late reply, that should fix your problem. Since I got here googling, I was hoping I could help someone else who needs this info.
I know it's already answered but I think this is a better answer. Yes, you can use dynamic fields for relations:
Post fixture:
return array(
'post1' => array(
'title' => 'My title',
'body' => 'My text',
),
Comment fixture:
return array(
'comment1' => array(
'text' => 'Comment text...',
'post_id' => $this->getRecord('post', 'post1')->id
),
PostTest.php
public $fixtures=array(
'post'=>'Post',
...
);
Yii docs CDbFixtureManager
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With