2011-08-04 12 views
5

私はYiiを使用しており、ユーザー、デバイス間にMANY_MANY関係を定義するusers_devicesテーブル(user_id、device_id)を持つデバイスが3つあります。Yiiはmany_many関係でモデルを見つける

私が探しているのは、ActiveRecord経由で特定のユーザー(users.id)に属するID(devices.id)からデバイスを見つける最も簡単な方法です。

シナリオでは、REST APIがデバイスを照会していますが、セキュリティ上の理由からデバイスがユーザーによって所有されていることを確認したいとします。事前に

$device = Devices::model()->findByPk($deviceId)->having(
    array('user_id' => $userId)); 

おかげで任意の助けのために、私はしばらくの間、これを研究してきましたし、エレガントな解決策を見つけることができません。このような

何かがアイデアです。

+0

users_devicesにはuser_idとdevice_idがプライマリ(複合)キーとして含まれていますか?そう、彼らが[ここ](http://learnyii.blogspot.com/2010/12/yii-on-many-many-relationships.html)のようにprmaryKey()をオーバーライドすることを忘れないでください。カスタム・モデルを使用してそのテーブルを検索するだけで、ユーザーとデバイスの関係(またはユーザー・デバイスの関係)を特定することができます。 – hobs

+0

あなたは、HAS_MANYではなくMANY_MANYを意味しました。 – hobs

+0

@Hobs、あなたは正しいです。 –

答えて

7

つまりは自分自身をそれを把握するために私を導いた、Yiiのフォーラムでいくつかの助けを得た:

$device = Device::model()->with('users')->find(array(
    'condition' => 'user_id = :userId AND device_id=:deviceId', 
    'params' => array(':userId' => Yii::app()->user->id, ':deviceId' => $_GET['id']))); 
1

ARを使用する必要がありますか?複雑な文を扱うとき、私はいつもquery builderを使用することを好む

...

$user = Yii::app()->db->createCommand() 
    ->select('id, username, profile') 
    ->from('tbl_user u') 
    ->join('tbl_profile p', 'u.id=p.user_id') 
    ->where('id=:id', array(':id'=>$id)) 
    ->queryRow(); 
+0

私はクエリビルダーを使用しなければならないと思う、Yii's Criteriaを使って複雑なクエリを扱うときに無限のデバッグ。ありがとう –

2

2つをとります。 Device.phpで

:その後、

// creates a users property within a Device, a container of associated Users 
public function relations() 
    { 
     return array(
      'users'=>array(self::MANY_MANY, 'User', // don't use HAS_MANY 
       'user_devices(user_id, device_id)'), // composite key assumed 
     ); 
    } 

要求されたデバイスが要求しているユーザが所有している場合は見つける:これは動作しますが、非効率的に不要なの多くを取得するのと同じように思え

$device = Device::model()->findByPk($deviceId); 
if ($device->users->findByPk($userId) == Null) 
    $device = Null; 

あなたは既にそのユーザーが誰であるのか、すでにActiveRecordを持っている可能性があることを既に知っているので、ユーザーレコード。このinnefficiencyを回避するために、Yiiのアジャイル開発の本は、親モデル(Device.php)内M2M関係クエリの生のSQLを使用しています。

// "Agile" uses a $user AR argument, you can use $userId instead 
public function doesUserOwnDevice($userId) 
{ 
    $sql = "SELECT user_id FROM user_devices WHERE 
    device_id=:deviceId AND user_id=:userId"; 
    $command = Yii::app()->db->createCommand($sql); 
    $command->bindValue(":deviceId", $this->id, PDO::PARAM_INT); 
    $command->bindValue(":userId", $userId, PDO::PARAM_INT); 
    return $command->execute()==1 ? true : false; 
} 

私は(同様にdeviceのモデルの名前をDeviceではなく、Devicesを使用テーブルの名前)。カットアンドペーストすればリファクタリングできます。 Userの場合も同様です。同様に "tbl_"接頭辞がないためです。

関連する問題