blog tutorial problem

Hello, i have a problem with "post/list" action of blog tutorial.

My code is modified - I drop tags column from Post table.

Relation in model Post.php:




	public function relations()

	{

		return array(

			'comments' => array(self::HAS_MANY, 'Comment', 'postId'),

			'author' => array(self::BELONGS_TO, 'User', 'authorId'),

			'tags' => array(self::MANY_MANY, 'Tag', 'PostTag(postId, tagId)'),

			'tagFilter' => array(self::MANY_MANY, 'Tag', 'PostTag(postId, tagId)','together'=>true,'joinType'=>'INNER JOIN','condition'=>'tagFilter.name=:tag'),

		);

	}



List action in PostController.php




	public function actionList()

	{		

		$criteria=new CDbCriteria;

		$criteria->condition='status='.Post::STATUS_PUBLISHED;

		$criteria->order='createTime DESC';

		

		$withOption = array('author','tags');

		if(!empty($_GET['tag']))

		{

			$withOption['tagFilter']['params'][':tag'] = $_GET['tag'];

			$postCount = Post::model()->with($withOption)->count($criteria);

		}

		else

			$postCount = Post::model()->count($criteria);

		

		$pages=new CPagination($postCount);

		$pages->applyLimit($criteria);


		$models=Post::model()->with($withOption)->findAll($criteria);


		foreach($models as $i=>$model) {

			$tags = array();

			foreach($model->tags as $tag) {

				$tags[] = $tag->name;

			}

			$model->tags = implode(',',$tags);

			$models[$i] = $model; 

		}

		

		$this->render('list',array(

			'models'=>$models,

			'pages'=>$pages,

		));

	}



Counting query works ok but the second one returns all posts from database.

So for ex: I have 1 post in database tagged as "tag5" and url r=post/list&tag=tag5.

The result is:




16:41:48.187865  	trace  	system.db.CDbCommand  	


Querying SQL: SELECT COUNT(DISTINCT `Post`.`id`) FROM `Post`  LEFT OUTER

JOIN `User` `author` ON (`Post`.`authorId`=`author`.`id`) LEFT OUTER JOIN

`PostTag` `tags_tags` ON (`Post`.`id`=`tags_tags`.`postId`) LEFT OUTER JOIN

`Tag` `tags` ON (`tags`.`id`=`tags_tags`.`tagId`) INNER JOIN `PostTag`

`tagFilter_tagFilter` ON (`Post`.`id`=`tagFilter_tagFilter`.`postId`) INNER

JOIN `Tag` `tagFilter` ON (`tagFilter`.`id`=`tagFilter_tagFilter`.`tagId`)

WHERE (status=1) AND (tagFilter.name=:tag)


16:41:48.188441 	trace 	application 	


Variable $postCount:1


16:41:48.189471 	trace 	system.db.ar.CActiveRecord 	


Post.findAll() eagerly


16:41:48.189771 	trace 	system.db.CDbCommand 	


Querying SQL: SELECT `Post`.`id` AS `t0_c0`, `Post`.`title` AS `t0_c1`,

`Post`.`content` AS `t0_c2`, `Post`.`contentDisplay` AS `t0_c3`,

`Post`.`status` AS `t0_c4`, `Post`.`createTime` AS `t0_c5`,

`Post`.`updateTime` AS `t0_c6`, `Post`.`commentCount` AS `t0_c7`,

`Post`.`authorId` AS `t0_c8`, `author`.`id` AS `t1_c0`, `author`.`username`

AS `t1_c1`, `author`.`password` AS `t1_c2`, `author`.`email` AS `t1_c3`,

`author`.`profile` AS `t1_c4` FROM `Post`  LEFT OUTER JOIN `User` `author`

ON (`Post`.`authorId`=`author`.`id`) WHERE (status=1) ORDER BY createTime

DESC LIMIT 10


16:41:48.191643 	trace 	system.db.CDbCommand 	


Querying SQL: SELECT `Post`.`id` AS `t0_c0`, `tags`.`id` AS `t2_c0`,

`tags`.`name` AS `t2_c1` FROM `Post` LEFT OUTER JOIN `PostTag` `tags_tags`

ON (`Post`.`id`=`tags_tags`.`postId`) LEFT OUTER JOIN `Tag` `tags` ON

(`tags`.`id`=`tags_tags`.`tagId`) WHERE (`Post`.`id` IN (38, 37, 36, 35,

34, 4, 3, 1))


16:41:48.192951 	trace 	system.db.CDbCommand 	


Querying SQL: SELECT `Post`.`id` AS `t0_c0`, `tagFilter`.`id` AS `t3_c0`,

`tagFilter`.`name` AS `t3_c1` FROM `Post` INNER JOIN `PostTag`

`tagFilter_tagFilter` ON (`Post`.`id`=`tagFilter_tagFilter`.`postId`) INNER

JOIN `Tag` `tagFilter` ON (`tagFilter`.`id`=`tagFilter_tagFilter`.`tagId`)

WHERE (`Post`.`id` IN (38, 37, 36, 35, 34, 4, 3, 1)) AND

(tagFilter.name=:tag)


16:41:48.193505 	trace 	application 	


Posts found: 8



When I remove $criteria from second query so it looks like:


$models=Post::model()->with($withOption)->findAll();

it works ok:




16:43:34.617446  	trace  	system.db.CDbCommand  	


Querying SQL: SELECT COUNT(DISTINCT `Post`.`id`) FROM `Post`  LEFT OUTER

JOIN `User` `author` ON (`Post`.`authorId`=`author`.`id`) LEFT OUTER JOIN

`PostTag` `tags_tags` ON (`Post`.`id`=`tags_tags`.`postId`) LEFT OUTER JOIN

`Tag` `tags` ON (`tags`.`id`=`tags_tags`.`tagId`) INNER JOIN `PostTag`

`tagFilter_tagFilter` ON (`Post`.`id`=`tagFilter_tagFilter`.`postId`) INNER

JOIN `Tag` `tagFilter` ON (`tagFilter`.`id`=`tagFilter_tagFilter`.`tagId`)

WHERE (status=1) AND (tagFilter.name=:tag)


16:43:34.618098 	trace 	application 	


Variable $postCount:1


16:43:34.619498 	trace 	system.db.ar.CActiveRecord 	


Post.findAll() eagerly


16:43:34.620127 	trace 	system.db.CDbCommand 	


Querying SQL: SELECT `Post`.`id` AS `t0_c0`, `Post`.`title` AS `t0_c1`,

`Post`.`content` AS `t0_c2`, `Post`.`contentDisplay` AS `t0_c3`,

`Post`.`status` AS `t0_c4`, `Post`.`createTime` AS `t0_c5`,

`Post`.`updateTime` AS `t0_c6`, `Post`.`commentCount` AS `t0_c7`,

`Post`.`authorId` AS `t0_c8`, `author`.`id` AS `t1_c0`, `author`.`username`

AS `t1_c1`, `author`.`password` AS `t1_c2`, `author`.`email` AS `t1_c3`,

`author`.`profile` AS `t1_c4`, `tags`.`id` AS `t2_c0`, `tags`.`name` AS

`t2_c1`, `tagFilter`.`id` AS `t3_c0`, `tagFilter`.`name` AS `t3_c1` FROM

`Post`  LEFT OUTER JOIN `User` `author` ON

(`Post`.`authorId`=`author`.`id`) LEFT OUTER JOIN `PostTag` `tags_tags` ON

(`Post`.`id`=`tags_tags`.`postId`) LEFT OUTER JOIN `Tag` `tags` ON

(`tags`.`id`=`tags_tags`.`tagId`) INNER JOIN `PostTag`

`tagFilter_tagFilter` ON (`Post`.`id`=`tagFilter_tagFilter`.`postId`) INNER

JOIN `Tag` `tagFilter` ON (`tagFilter`.`id`=`tagFilter_tagFilter`.`tagId`)

WHERE (tagFilter.name=:tag)


16:43:34.621351 	trace 	application 	


Posts found: 1



but it doesnt use criteria which are very important :) It’s my first approach to Yii so please dont be angry if its trivial :)

Any ideas?

If I understood you, The problem is that you can’t get a post by Tag, Am I right ?

You can use isset(Determine if a variable is set and is not NULL.) in place of empty :)


if(isset($_GET['tag']))

However, I don’t know if it is going to help you. Please answer my first question :)

Not exactly :)

Lets say that URL is r=post/list&tag=tag5 so i’m looking for all posts by tag “tag5”.

This works as I want to and returns "1" (so there is only one post with tag "tag5"




$postCount = Post::model()->with($withOption)->count($criteria);



But this returns all posts instead only one.




$models=Post::model()->with($withOption)->findAll($criteria);



When i remove $criteria from findAll() it returns one post as it should. But I need these $criteria :)

Check if this works




$models=Post::model()->with($withOption)->together()->findAll($criteria);



/Tommy

Yeah, lack of "together()->" was a problem. Thanks tri!