0

私のアプリには3つのテーブルがあります。

Users
Profiles
Friends

ユーザーには1つのプロファイルがあり、プロファイルには1人のユーザーがいて、多くの友達がいます。友達にはたくさんのプロフィールがあります。

プロファイルモデルには、プロファイルのプロファイルのリストを取得するメソッドがあります(ただし、ユーザーテーブルから取得した関連するユーザー名を使用します)。

public function getFriends($username) {

   return $this->find('all', array(
     'conditions' => array(
       'User.username' => $username,
        'Friend.status' => 1
      )
   ));

}

したがって、ユーザー名がユーザーと一致し、友人のステータスが1である場合に一致するプロファイルのリストを取得する必要があります。これを行うにはどうすればよいですか?

DBを理解できるように、関連付けも投稿します。

ユーザーモデル:

public $hasOne = 'Profile';

プロファイルモデル:

public $belongsTo = 'User';

public $hasMany = array(
    'ProfileFrom'=>array(
        'className'=>'Friend',
        'foreignKey'=>'profile_from'
    ),
    'ProfileTo'=>array(
        'className'=>'Friend',
        'foreignKey'=>'profile_to'
    )
);

public $hasAndBelongsToMany = array(
    'Friendship' => array(
        'className' => 'Profile',
        'joinTable' => 'friends',
        'foreignKey' => 'profile_from',
        'associationForeignKey' => 'profile_to'
    )
);

public $actsAs = array('Containable');

フレンドモデル:

public $belongsTo = array(
      'UserFrom'=>array(
         'className'=>'Profile',
         'foreignKey'=>'profile_from'
      ),
      'UserTo'=>array(
         'className'=>'Profile',
         'foreignKey'=>'profile_to'
      )
   );

public $actsAs = array('Containable');
4

1 に答える 1

0

これは複雑に見えます。フェッチするデータの選択を非常に簡単にするContainable(コアのcakephpの動作)を確認することをお勧めします(特に、過剰なデータの選択を防ぐことに関して)。アプリ全体に使用することを検討してください。

関連付けられたフレンドモデルで検索するようにケーキに指示しようとしているようですが、私が正しい場合、フレンドに存在する唯一の関連付けは、ProfileToおよびProfileFromとしてエイリアスされます。だから、ケーキは「友達」をどこで捕まえるのかわからないと思います。ただし、将来的には、エラーも投稿すると便利です。

可能な修正については、以下の私の提案を参照してください。


今のところ、次のことができます。ProfileModelの場合:

function getFriends($username) {
    //Start by getting User's ID
    $user = $this->User->find(
        'first',
        array(
            'conditions' => array(
                'User.username' => $username
            )
        )
    );
    //User's ID is now $user['User']['id']

    //Fetch user's profile with associated friends
    $this->Behaviors->attach('Containable');
    $profileAndFriends = $this->find(
        'first',  //Because User hasOne Profile, so we'll fetch this one profile.
        array(
            'conditions' => array(
                'Profile.user_id' => $user['User']['id']
            ),
            //We'll want to fetch all associated Friend records (which are linked to the Profile model as ProfileFrom and ProfileTo
            'contain' => array(
                'ProfileFrom' => array(
                    'conditions' => array(
                        'status' => 1
                    )
                ),
                'ProfileTo' => array(
                    'conditions' => array(
                        'status' => 1
                    )
                )
            )
        )
    );
    return $profileAndFriends;
}

このように動作するはずです。したがって、FriendsControllerで、これで実行できるようになります$this->Friend->UserTo->getFriends('cameron'); 。これにより、ユーザー名が「cameron」のユーザーに属するプロファイルと、このプロファイルに関連付けられているすべてのフレンドがフェッチされます。


ただし、まだ気になる小さなことが1つあります。それは、ProfileToがProfileに関連付けられていないというエラーが発生したという事実です。これは、例のように、関係が明らかに定義されているという奇妙なことです。原因はあなたの協会の定義の誤りかもしれませんが、私にはわかりません。


上記のコードが機能しない場合は、もう1つの提案として、contain配列を次のように置き換えます。

            'contain' => array(
                'Friendship' => array(
                    'conditions' => array(
                        'OR' => array(
                            'Friendship.profile_from' => 'Profile.id',
                            'Friendship.profile_to' => 'Profile.id',
                        )
                    )
                )
            )
于 2012-04-13T14:13:11.710 に答える