使用Yii显示来自2个模型的数据
我试图从两个表中选择数据,并在分页的网格视图中显示数据。 问题在于Yii使用SQL连接加入数据(因为我告诉它这样做),并且因为它没有显示每页正确数量的项目。
为了明确,我正在从topics
和messages_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的格式化所复杂化:
此外,您还可以确保直接设置这些属性,以便将您的查询实际分解为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 m
或messages 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;
获取主题。