Yii Framework Как получить доступ к реляционной ActiveRecord по ID и получить дальше? - PullRequest
3 голосов
/ 08 ноября 2011

Так что я немного заблудился с CActiveRecord в Yii.

Допустим, у меня есть следующие простые модели:

  • Post
    • id
    • контент
  • Комментарий
    • id
    • контент
    • post_id

Итак, оставьте комментарий HAS_MANY, я думаю, что это описание должно быть достаточно очевидным из этого описания.

Что если я хочу получить все комментариев, а затем получить конкретный комментарий для чего?Как будто я хочу отобразить список комментариев к сообщению, но показать содержание только одного из них (по 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);

Или мне снова нужно обернуть свой цикл над комментариями?

Я просто пытаюсь воспользоваться тем, что предлагает Yii, прежде чем писать дополнительный код.В документации всегда предполагается, что вам всегда нужны все реляционные данные, в ней не указано, как выбирать части реляционных данных.

1 Ответ

1 голос
/ 09 ноября 2011

Ответ на первый вопрос

$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),
));

Второй вопрос: что вы подразумеваете под «следующим» и «предыдущим» комментарием?Рядом с чем?Идентифицировать или создать_время?

Вы можете сделать для него что-то вроде этого (для предыдущего: 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,
));

Вы можете получить больше информации по этой теме здесь а также из официальной ссылки на класс для CActiveRecord.find ()

Обновление

Если вы хотите получить все комментарии из БД, а затем получить одинпо id вы можете сделать это следующим образом:

$ post-> comments - это просто массив.Таким образом, вы можете пройтись по нему и получить свой, как вы описали в теме.

Но также вы можете добавить новый метод в класс модели Post (не комментарии, потому что это массив), например "findCommentById":

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

    return null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...