たとえば、多対多の情報を保持するための中間テーブルを作成するのが最善の方法だと思います。
CREATE TABLE `categories_tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_categories` int(11) NOT NULL,
`id_tags` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
ALTER TABLE `categories_tags`
ADD CONSTRAINT `categories_tags_ibfk_1` FOREIGN KEY (`id_categories`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `categories_tags_ibfk_2` FOREIGN KEY (`id_tags`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
と...
CREATE TABLE `tags_urls` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_tags` int(11) NOT NULL,
`id_urls` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
ALTER TABLE `tags_urls`
ADD CONSTRAINT `tags_urls_ibfk_1` FOREIGN KEY (`id_tags`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `tags_urls_ibfk_2` FOREIGN KEY (`id_urls`) REFERENCES `urls` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
これらのテーブル間の関係でスルーを使用できます。
あなたのカテゴリモデルでは:
public function relations()
{
return array(
'categoryTags' => array(self::_MANY, 'CategoriesTags', 'id_categories'),
'tags' => array(self::HAS_MANY, 'Tag', 'id_tags', 'through'=>'categoryTags'),
'tagsUrls' => array(self::HAS_MANY, 'TagUrl', 'id_tags', 'through'=>'tags'),
'urls' => array(self::HAS_MANY, 'Url', 'id_url', 'through'=>'tagsUrls'),
);
}
特定のカテゴリのすべての URL を呼び出すには、次のことができるはずです。
$model = Category::model()->findByPk($categoryId);
$model->urls; // will be an array of url models that belong to the category.
[編集] 質問を読み直した後、上記の編集を追加しました。私はテストしていません。コードをいくつか (または多く) 編集する必要があるかもしれませんが、原則は理論的には機能するはずです。「スルー」リレーション データを取得するためのより迅速な方法があるかもしれませんが、実際には以前に 2 つの多対多リレーションシップでスルーを使用したことがないため、自分で試す必要はありませんでした。