【问题标题】:Relational fixtures in YiiYii 中的关系夹具
【发布时间】:2011-09-15 01:47:34
【问题描述】:

如何在 Yii 中设置带有关系的装置?例如,post 可以有 cmets,如何在 fixture 中引用 post id 来创建 cmets?

后夹具:

return array(
  'post1'=>array(
    'title'=>'My title',
    'body'=>'My text',
  ), 
  ...

评论夹具:

return array(
  'comment1'=>array(
    'text'=>'Comment text...',
    'post_id'=> ???
  ), 

【问题讨论】:

  • 我们在这里讨论的是关系查询吗?
  • 不是吗?我只想创建与生产系统中的关系类似的装置(用于单元测试)。
  • 我的错。先生,我会调查的。

标签: php yii fixtures


【解决方案1】:

我不知道是否有动态的方法来做到这一点,但以下应该可以工作:

后夹具:

return array(
  'post1' => array(
    'id' => 1 
    'title' => 'My title',
    'body' => 'My text',
), 

评论夹具:

return array(
  'comment1' => array(
    'text' => 'Comment text...',
    'post_id' => 1
),

【讨论】:

  • 如果有人想知道,这确实有效 - 尽管文档提到 id 字段是动态生成的,并声明不要设置它们。
  • 由于加载夹具的顺序由 php readdir 命令列出夹具文件的顺序决定,因此可能需要暂时禁用外键约束。跨度>
【解决方案2】:

据我所知,您可以使用初始化脚本而不是经典的固定装置。 Yii documentation 内容如下:

也有可能我们不喜欢默认的重置方式 表,即截断它并将其与夹具数据一起插入。如果 既然如此,我们可以为 特定的夹具文件。脚本必须命名为表名 后缀为 .init.php。例如,初始化脚本 Post 表是 Post.init.php。当 CDbFixtureManager 看到 这个脚本,它将执行这个脚本而不是使用默认的 重置表格的方法。

因此,在您的情况下,您将拥有protected/tests/fixtures/Comment.init.php,而不是protected/tests/fixtures/Comment.php

// 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';

虽然我意识到这是一个很晚的回复,但这应该可以解决您的问题。自从我来到这里使用谷歌搜索,我希望我可以帮助需要这些信息的其他人。

【讨论】:

  • 感谢您的回复,即使有时间延迟!我希望它对将来的人有所帮助。
【解决方案3】:

我知道它已经回答了,但我认为这是一个更好的答案。 是的,您可以为关系使用动态字段:

后夹具:

return array(
  'post1' => array(
    'title' => 'My title',
    'body' => 'My text',
), 

评论夹具:

return array(
  'comment1' => array(
    'text' => 'Comment text...',
    'post_id' => $this->getRecord('post', 'post1')->id
),

PostTest.php

public $fixtures=array(
    'post'=>'Post',
    ...
);

Yii 文档CDbFixtureManager

【讨论】:

  • 我试过了,但没有成功,我在引导或配置上有什么不同吗? cdbFixtureManager 中的 _records 对我来说始终为空
  • 什么是“_records”?它是否适用于硬编码 id ?如果不是,那么它与我的答案无关,您应该寻求有关创建测试和固定装置的帮助。提示:我认为 $fixture 数组中的顺序很重要,因此请确保首先包含主表(这里 'post' 是 $fixtures 中的第一个元素,然后应该是 'comment')。
  • 除了使用硬编码的 id 时不需要其他配置。我的猜测是你拼错了一些东西。例如 cdbFixtureManager 没有任何“getRecords”方法。它有“getRecord”并且应该返回一个 ActiveRecord 对象。也许您已经使用“->id”来获取 id,但它应该与模型中的 id 匹配。
  • 我想我找到了原因:CDBFixtureManager 按照 readdir php 函数给出的顺序从夹具文件夹中加载所有夹具文件。要以特定顺序加载灯具,您需要按该顺序将它们添加到 $fixture 数组中,并在“fixtures”文件夹中创建一个空的 init.php 文件。希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
相关资源
最近更新 更多