【问题标题】:Yii Framework How to Access Relational ActiveRecord by ID and get next?Yii Framework 如何通过 ID 访问关系 ActiveRecord 并获取下一步?
【发布时间】:2011-11-08 04:27:51
【问题描述】:

所以我对 Yii 中的 CActiveRecord 有点迷失了。

假设我有以下简单模型:

  • 发布
    • 身份证
    • 内容
  • 评论
    • 身份证
    • 内容
    • post_id

所以发表 HAS_MANY 评论,我认为从该描述中可以看出这种关系。

如果我想获得所有 cmets,然后在其中获得特定评论,该怎么办?就像我想显示一个帖子的 cmets 列表,但只显示其中一个的内容(通过 PK)。

所以我有:

$this->post = Post::model()->with('comments')->findByPk( $pid );
 // this next line is an extra DB Query, right?
$this->comment = Comment::model()->findByPk( $cid );

但我想要类似的东西:

$this->post = Post::model()->with('comments')->findByPk( $pid );
// this is not valid code because the comments is an array
$this->comment = $this->post->comments->findByPk( $cid ); // <---

我是否必须自己将其包装在一个循环中才能第二次实现 findByPk?

我的第二个问题是,我可以执行以下操作吗?

$this->post = Post::model()->with('comments')->findByPk( $pid );
$this->comment = Comment::model()->findByPk( $cid );
// Get the PK of the next and previous comments from the $cid comment
// again, not valid code
$this->next = $this->post->NextComment($this->comment);
$this->prev = $this->post->PreviousComment($this->comment);

或者我是否需要再次将自己的循环包裹在 cmets 上?

在编写额外代码之前,我真的只是想利用 Yii 提供的功能。该文档始终假定您始终需要所有关系数据,它没有指定如何选择部分关系数据。

【问题讨论】:

    标签: php activerecord yii


    【解决方案1】:

    第一个问题的答案是

    $post = Post::model()->with('comments')->find('t.id = :post_id AND comments.id = :comment_id', array(
        ':post_id' => $somePostId,
        ':comment_id' => $someCommentId,
    ));
    

    $post =  Post::model()->findByPk($somePostId);
    $comments = $post->comments(array(
        'condition' => 'comments.id = :comment_id',
        'params' => array(':comment_id' => $someCommentId),
    ));
    

    第二个问题:“下一个”和“上一个”评论是什么意思? 旁边是什么?要 id 还是要 create_time?

    你可以为它做这样的事情(对于以前的 create_time):

    $post =  Post::model()->findByPk($somePostId);
    $comment = Comment::model()->findByPk(someCommentId);
    $previousComment = $post->comments(array(
        'condition' => 'comments.create_time < :comment_create_time',
        'params' => array(':comment_create_time' => $comment->create_time),
        'limit' => 1,
    ));
    

    您可以从here 获取有关此主题的更多信息,也可以从CActiveRecord.find() 的官方类参考中获得更多信息

    更新

    如果你想从 db 中获取所有 cmets 而不是通过 id 获取一个,你可以这样做:

    $post->cmets 只是一个数组。因此,您可以遍历它并按照主题中的描述获得您的。

    但您也可以向 Post 模型类(不是 cmets,因为它是一个数组)添加一个新方法,例如“findCommentById”:

    public function findCommentById($id)
    {
        foreach ($this->comments as $comment)
            if ($comment->id == $id)
                return $comment;
    
        return null;
    }
    

    【讨论】:

    • "next" 和 "previous" 不相关,你的例子很好,我只是不知道如何找到相关的 cmets。所以我认为要摆脱这一点的是,我可以写$post-&gt;comments(array(...)); 来查询具有附加条件的相关 cmets,对吗?我从来都不是很清楚,但我会试试你在这里发布的内容。
    • 这个答案的唯一问题是我想获得 所有 cmets,但 从组中挑选一个特定的。我只是想避免再次访问数据库,如果功能存在,我不想编写自己的查找循环。
    • 我已经更新了我的答案,没有这样的功能,但你也可以用 Behavior 添加它。或者你可以尝试在 Yii 扩展页面找到它。
    • 好的,所以它不是现有功能。感谢你的回答。我会考虑使用行为,但你的解决方案现在很简单(只需将其放入模型中)
    猜你喜欢
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2016-06-17
    相关资源
    最近更新 更多