Related tags, search by tags in Cheesecake-Photoblog
An often repeated question on the CakePHP Group relates to filtering hasAndBelongsToMany associations or finding related hasAndBelongsToMany associations. To give a real life example and make it more clear - In Cheesecake-Photoblog a photo has and belongs to many tags. Simple tasks like finding all tags that belong to a photo or all photos that belong to a tag is handled easily by CakePHP but there are two common requirements of our tagging system
#1 Finding all photos which belong to a combination of tags, eg: all photos which have the tags kanha and tiger
#2 Finding related tags - all other tags which belong to photos returned for a particular tag
And I am sure these are common requirements of any hasAndBelongsToMany relationship... I have always believed that while a framework can do a lot when it comes to automating SQLs there will always be times when you need to write your own SQL and these two problems were apt for writing a bit of custom SQL rather than creating models on join tables etc.
To solve the #1 we have the following method in the Photo model
-
return false;
-
}
-
-
$criteria = ' AND '.$criteria;
-
}
-
-
$prefix = $this->tablePrefix;
-
$offset = $limit * ($page-1);
-
$photos = $this->query("SELECT Photo.id,Photo.filename,Photo.title,Photo.created, COUNT(DISTINCT tags.tag) AS uniques
-
FROM {$prefix}photos Photo, {$prefix}photos_tags photos_tags, {$prefix}tags tags
-
WHERE Photo.id = photos_tags.photo_id
-
AND tags.id = photos_tags.tag_id
-
GROUP BY photos_tags.photo_id
-
ORDER BY Photo.created DESC
-
LIMIT $offset, $limit");
-
return $photos;
-
}
and for #2 we have the following in the Tag model
-
$prefix = $this->tablePrefix;
-
if($tagsCount> 0){
-
$query = "SELECT Tags.*, COUNT(pt.photo_id) AS count
-
FROM {$prefix}photos_tags pt, {$prefix}tags Tags
-
WHERE pt.photo_id IN (
-
SELECT pt.photo_id FROM {$prefix}photos_tags pt, {$prefix}tags Tags
-
WHERE pt.tag_id = Tags.id
-
AND Tags.tag IN ({$tagsString})
-
GROUP BY pt.photo_id
-
HAVING COUNT(pt.photo_id)={$tagsCount})
-
AND Tags.tag NOT IN ({$tagsString})
-
AND Tags.id = pt.tag_id
-
GROUP BY pt.tag_id
-
ORDER BY count DESC";
-
$relatedTags = $this->query($query);
-
return $relatedTags;
-
}
-
}
The usage of the function and the code itself is pretty self explanatory anyone can easily adapt it use with their own HABTM associations, however there is room for improvement - this code can be made into a behavior and thus be more generic and reusable. If anybody reading this does accomplish it do drop a line here.....
About this entry
You’re currently reading “ Related tags, search by tags in Cheesecake-Photoblog ,” an entry on SANIsoft – PHP for E Biz
- Published:
- 7.18.07 / 12:39pm
- Category:
- CakePHP, Cheesecake, MySQL
- Author:
- Tarique Sani
No comments
Jump to comment form | comments rss | trackback uri