使用Yii显示来自2个模型的数据

我试图从两个表中选择数据,并在分页的网格视图中显示数据。 问题在于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字段进行分组,无论如何,我无法这样做,因为存在用like语句搜索的where条件。

谢谢

编辑:

这是我的行动代码:

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

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

您可以尝试告诉您的查询在结果中使用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的格式化所复杂化:

  • $ criteria-> select就是您想要选择的列的列表。
  • $ criteria->条件恰好是WHERE条件,我真的更喜欢使用一个字符串到一个数组,因为使用字符串允许我使用我放在这里的确切条件。
  • $ criteria-> join紧跟在CActiveDataProvider构造函数中指定的$ model-> tableName()之后。
  • $ criteria-> group被添加到查询的末尾,您只需指定分组列即可。
  • 此外,您还可以确保直接设置这些属性,以便将您的查询实际分解为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下的表将被称为t 。 任何其他表也必须在连接条件中指定(非常像messages mmessages AS m ),否则您可能会得到column xxxx is ambiguous警告。

    对于任何您可能遇到的问题,请不要泄漏CDbCriteria和CActiveDataProvider的机会。


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

    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; 获取主题。

    链接地址: http://www.djcxy.com/p/60847.html

    上一篇: Showing data from 2 models in a grid with Yii

    下一篇: How to fix the Error CDbException in Yii?