フレンドシップには 2 つの方向性があるため、フレンドシップ アソシエーションを実装するにはいくつかの方法があります。ユーザー A はユーザー B と友達であると言えますが、ユーザー B はユーザー A と友達でもあります。
人がデータベースで友情を作成するとき。この友情を両方向で表すには、結合テーブルに 2 つのレコードを作成する必要があります (双方向が必要であると仮定します)。
それは方向の概念をカバーしています。
レコードが更新されると、CakePHP はデフォルトでレコードのすべての結合データ行を消去するため、レコードが消えるという問題が発生している可能性があります。HABTM の「unique」オプションの説明を見てください。
unique : true (デフォルト値) の場合、レコードを更新するとき、cake は新しいレコードを挿入する前に、まず外部キー テーブル内の既存の関係レコードを削除します。そのため、更新時に既存の関連付けを再度渡す必要があります。
つまり、レコードを更新するときは常に HABTM データを含める必要があります。そうしないと、それらのレコードは消去され、渡されたもので更新されます。
作成できる最も基本的な友情のセットアップには、2 つのテーブルが含まれます。
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `users_users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`friend_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `user` (`user_id`),
KEY `friend` (`friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
最初のテーブル 'users' はユーザー データを保持し、2 番目の 'users_users' は HABTM 結合テーブルです。自分自身に参加しているため、users_users であることに注意してください。
CakePHP で 2 つのモデルを作成する必要があります。
1 つ目は、システム内のユーザーを記述する User.php です。これを機能させるために、CakePHP のほとんどのデフォルトを使用します。したがって、HABTM は 'Friend' という 1 行にすぎません。
class User extends AppModel
{
var $name = 'User';
var $hasAndBelongsToMany = array(
'Friend'
);
}
ここで、CakePHP はテーブル users_friends が見つからないと文句を言います。Friend モデルを作成する必要がありますが、代わりに users テーブルをポイントします。
class Friend extends AppModel
{
var $name = 'Friend';
var $useTable = 'users';
}
ここで、CakePHP は結合として users_users テーブルを使用します。Friend モデルは、友人であるユーザーを記述するようになりました。
双方向で友達を作成する必要があることを理解することが重要です。ユーザー A がユーザー B と友達であると言うデータを保存する場合、ユーザー B も保存し、ユーザー A と友達であると言う必要があります。
エイリアスを使用して友情の二重方向を定義する別の回答がここにありますが、アプリケーションで必要とされない可能性がある CakePHP の余分な SQL クエリ作業が追加されるため、それを実装しないことをお勧めします。ユーザー A のレコードを読み取る場合、ユーザー A の友人が誰であるかを知る必要があるだけで、その逆は必要ありません。
ユーザー レコードが更新されたときに友情が双方向になるようにする動作を作成できます。その方が効率的でしょう。
注:私のコード例は、現在使用しているCakePHP 1.3用ですが、2.x でも問題なく動作するはずです。