0

CakePHP 2 でフレンドシップを設定するのに問題があります。

usersfriendsの 2 つのデータベース テーブルがあります。私の users テーブルには次の列があります。

  • ID
  • Eメール
  • パスワード

私の友人テーブルには次の列があります。

  • ID
  • ユーザーID
  • フレンドID
  • 承認済み

Users モデルで hasAndBelongsToMany 関係として設定された友人がいます。

<?php
class User extends AppModel {
    public $hasAndBelongsToMany = array(
        'Friends' => array(
            'className' => 'User',
            'joinTable' => 'friends',
            'foreignKey' => 'user_id',
            'associationForeignKey' => 'friend_id',
            'unique' => true
        )
    );
}

ここで、ユーザーの友達を取得しようとすると、指定されたユーザーが開始した友情のみがリストされます。つまりuser_id、ユーザー ID と等しい場所です。friend_id他の人がリクエストを開始した可能性のある場所 (つまり、現在のユーザーの ID が列にある場所) の友人は表示されません。

user_idまたはfriend_id列が特定の ID と等しいレコードを取得するにはどうすればよいですか?

4

1 に答える 1

2

HABTM の仕組みを理解していないと思います。本のこの部分を読んでください。関係を機能させるには、テーブルに加えて friends_users テーブルが必要です。このように設定する場合は、フレンドシップを多くのユーザーを持ち、所属するものとして定義する必要があると思います。

ただし、現在のセットアップで HABTM 関係が必要かどうかは疑問です。ユーザーには多くの友達がいるようです。それだけです。その関係の使用を検討すると、期待どおりに関連する ID が得られます。フレンドの属しているユーザーを定義することを忘れないでください。


これが私の正規の Cake 2.0 Friendship チュートリアルです。CakePHP 2.1 をダウンロードしたので、新たなスタートを切ることができました。最初にセキュリティ ソルトと暗号を変更し、次にデータベース接続を追加しました。次に、データベースを次のように構成しました。

データベース:

usersテーブル:

id         | int(11)
created    | datetime
username   | varchar(255)

friendshipsテーブル:

id         | int(11)
user_from  | varchar(255)
user_to    | varchar(255)
created    | datetime
status     | varchar(50)

明らかに、users テーブルにはさらに多くのものを含めることができますが、これは私が必要とする最小限のものです。

モデル:

さて、これはトリッキーな部分です。User モデルで定義した関係を次に示します。

class User extends AppModel {
/* Other code if you have it */
        var $hasMany = array(
          'FriendFrom'=>array(
             'className'=>'Friendship',
             'foreignKey'=>'user_from'
          ),
          'FriendTo'=>array(
             'className'=>'Friendship',
             'foreignKey'=>'user_to'
          )
       );
       var $hasAndBelongsToMany = array(
          'UserFriendship' => array(
              'className' => 'User',
              'joinTable' => 'friendships',
              'foreignKey' => 'user_from',
              'associationForeignKey' => 'user_to'
            )
       );
/* Again, other code */
}

これが私の友情モデルです:

class Friendship extends AppModel {
/* Other code if you have it */
    var $belongsTo = array(
      'UserFrom'=>array(
         'className'=>'User',
         'foreignKey'=>'user_from'
      ),
      'UserTo'=>array(
         'className'=>'User',
         'foreignKey'=>'user_to'
      )
   );
/* Again, other code */
}

モデルに関する注意: フレンドシップ モデルは 2 人のユーザーに属します。ユーザー モデルには 3 つの関連付けがあります。User Model の 2 つの hasMany リレーションシップはどちらも Friendship モデルのデータにアクセスするためのエイリアスであるため、コントローラから$this->User->FriendToまたはを使用して Friendship モデルにアクセスできます。$this->User->FriendFrom私は最初、Friendship モデルのセットアップを反映して、これらの UserFrom と UserTo を呼び出しましたが、Cake は類似点についてひっかかったので、それらをより明確にする必要がありました。

コントローラーとビュー: ベイク ユーティリティを使用して、コントローラーとビューをベイクしました。次に、2 人のユーザー (Daniel と Martin) を作成し、Daniel から Martin への新しいフレンドシップを作成しました。ステータスはrequestedです。その後、友好度を に更新しましたconfirmed

次のビューレス カスタム ユーザー アクションを作成して、UsersController からの友情に関するデータ取得を示します。

public function test() {
  $data = $this->User->FriendFrom->find('all', 
    array(
      'conditions'=>array('user_from'=>1), 
      'contain'=>array('UserTo')
    )
  );
  die(debug($data));
}

この検索で​​は、UserModel の hasMany 関係を使用して Friendship モデルにアクセスし、ID が 1 のユーザーが関係を開始した関係の関連データをuser_from取得します。user_to

あなたの特定の発見

マーティン、あなたが探している発見は、このシステムでは非常にシンプルです。別の方法で行うこともできますが、関係に常に2つの側面がある限り、常に同様の方法を使用することになります. あなたがしなければならないのは、あなたのユーザーIDがuser1またはuser2のいずれかである関係のリストを取得することです(私の場合、関係を開始した人を知るために、それらをuser_toおよびuser_fromとして保存しています-これがあなたを怖がらせたものだと思います)。次に、配列全体を繰り返し処理し、その特定の配列で私が user1 か 2 かに基づいて、関連するフレンド データを選択します。これは非常に単純な方法で、ユーザー モデルに入れるだけです。ダイを変更します(debug()); コントローラーからreturn $friendslist呼び出して配列を取得できるようにします。

public function getFriends($idToFind) {
  $data = $this->FriendFrom->find('all', 
    array(
      'conditions'=>array(
        'OR'=> array(
            array('user_to'=> $idToFind),
            array('user_from'=> $idToFind)
        )
        )
    )
  );
  $friendslist = array();
  foreach ($data as $i) {
    if ($i['FriendFrom']['user_from'] == $idToFind){
        $friendslist[] = $i['UserTo'];
    }
    elseif ($i['FriendFrom']['user_to'] == $idToFind){
        $friendslist[] = $i['UserFrom'];
    }
  }

  die(debug($friendslist));
}
于 2012-06-30T22:25:47.853 に答える