使用Yii显示网格中2个模型的数据

时间:2012-11-14 15:37:04

标签: php mysql yii

我正在尝试从两个表中选择数据并在分页网格视图中显示该数据。问题是,Yii正在使用SQL连接加入数据(因为我告诉它要这样做)并且因为它没有显示每页的正确数量的项目。

为了明确说明,我选择topicsmessages_in_topics,然后我加入

$criteria->together = true;

这使得MySQL为每条消息(以及相关主题)返回一行。例如:

id_topic    topic    id_messages    message

1           topic1   1              message1_in_topic1
1           topic1   2              message2_in_topic1
1           topic1   3              message3_in_topic1
2           topic2   4              message1_in_topic2
2           topic2   5              message2_in_topic2

只有2个主题,但Yii的分页器认为有5个。

“修复”这个的最快方法是通过id_topic字段进行分组,无论如何,我不能这样做,因为有一个where条件用like语句进行搜索。

谢谢

编辑:

这是我的行动代码:

$criteria = new CDbCriteria;

$get_s = Yii::app()->request->getQuery('s', '');
if( $get_s ){
    $criteria->compare("topic_title", $get_s, true);
    $criteria->compare("message_text", $get_s, true, 'OR');
}

$criteria->with = array('messages');
$criteria->addCondition(array( ......  )); <--- some rules like if the topic is validated...

$dataProvider = new CActiveDataProvider('Topics', array(
    'criteria'=>$criteria,
    'pagination=>array('pageSize'=>15)
));

2 个答案:

答案 0 :(得分:1)

实际上,所发生的事情是显示的信息与您的消息有关。重复的主题值是因为这些主题是与消息相对应的相关数据。

您可以尝试告诉您的查询在结果中使用GROUP BY ...

SELECT t.id_topic, t.topic, COUNT(m.id_messages)
  FROM topics t LEFT JOIN messages m ON t.id_topic = m.id_topic
GROUP BY t.id_topic

这种方式,或多或少,您可以显示每个主题的消息数。 如果你向我们展示你的SQL,我可以帮助你更多。

编辑:看到您的代码后,我的猜测是: $ criteria = new CDbCriteria;

$get_s = Yii::app()->request->getQuery('s', '');
if( $get_s ){
    $criteria->compare("topic_title", $get_s, true);
    $criteria->compare("message_text", $get_s, true, 'OR');
}

$criteria->with = array('messages');
$criteria->addCondition(array( ......  )); <--- some rules like if the topic is validated...

$dataProvider = new CActiveDataProvider('Topics', array(
    'criteria'=>$criteria,
    'pagination=>array('pageSize'=>15)
));

您可以通过仅使用CDbCriteria的三个基本属性来填充yii的格式来确保查询不复杂:

  1. $ criteria-&gt; select 正是您要选择的列的列表。
  2. $ criteria-&gt;条件正好是WHERE条件,老实说,我更喜欢将字符串用于数组,因为使用字符串可以让我使用我放在这里的确切条件。
  3. 在您在CActiveDataProvider构造函数中指定的$ model-&gt; tableName()之后立即附加
  4. $ criteria-&gt; join
  5. 在查询结尾处添加
  6. $ criteria-&gt; group ,您只需指定分组列。
  7. 此外,您还可以确保直接设置这些属性,因此您实际上将查询分解为CDbCriteria对象。例如:

    SELECT t.id_topic, t.topic, COUNT(m.id_messages)
      FROM topics t LEFT JOIN messages m ON t.id_topic = m.id_topic
    GROUP BY t.id_topic
    

    就像这样

    /*1*/ $criteria->select = 't.id_topic, t.topic, COUNT(m.id_messages)';
    /*2*/ $criteria->condition = 't.topic_title LIKE %'.$get_s.'% OR ...';/* add your conditions here*/
    /*3*/ $criteria->join = 'LEFT JOIN messages m ON t.id_topic = m.id_topic'; //Full join statement here, including the nature of the join.
    /*4*/ $criteria->group = 't.id_topic';
    

    重要:考虑到您将Topics类名称传递给CActiveDataProvider构造函数后,Topics下的表格将被称为{{1 }}。在连接条件中也必须指定任何其他表(非常类似于tmessages m),否则您可能会收到messages AS m警告。

    如果您有任何问题,请不要错过CDbCriteriaCActiveDataProvider

答案 1 :(得分:0)

问题不在于分页符,而在于您查询。如果您运行查询:

SELECT *
FROM topics as t
INNER JOIN messages_in_topics as mt
    ON mt.topics_id = t.id
INNER JOIN messages as m
    ON m.id = mt.messages_id

您将获得5个结果,如上例所示。

更重要的是,你想做什么?

此外,您的表显示MANY_MANY关系(message1有2个主题,topic1有3条消息),您的数据库设置正确吗,您的模型关系是否相应配置?

您是否尝试在一行中显示每个主题中的所有消息?

您是否尝试显示所有主题并列出包含该主题的每条消息?

假设您已正确设置关系,您可以使用:$messages=$topics->messages;并获取包含所有列出的消息的数组。

相反,您可以$topics=$messages->topics;来获取主题。