2011-08-04 118 views
5

我使用Yii並有3個表格:用戶,具有user_devices表格(user_id,device_id)的設備來定義它們之間的MANY_MANY關係。Yii通過many_many關係找到模型

我正在尋找的是從其ID(devices.id)通過ActiveRecord屬於特定用戶(users.id)查找設備的最簡單方法。

該場景是REST API查詢設備,但出於安全原因,我想驗證設備是由用戶擁有的。

像這樣的理念是:

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

在此先感謝您的幫助,我一直在研究這一段時間,並不能找到一個完美的解決方案。

+0

用戶設備是否將user_id和device_id作爲主(複合)鍵?是的,不要忘記像他們[在這裏](http://learnyii.blogspot.com/2010/12/yii-on-many-many-relationships.html)一樣覆蓋prmaryKey()。您可以使用自定義模型在該表上查找以識別用戶設備關係(或缺少一個)。 – hobs

+0

你的意思是MANY_MANY而不是HAS_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的Criteria處理複雜查詢時進行無盡的調試。謝謝 –

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的敏捷開發的書籍使用原始SQL父模型中M2M關係查詢(Device.php):

// "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,而不是Devices爲模型(同樣device的名稱表格的名稱)。重構如果你剪切和粘貼。同樣適用於User。同樣因爲缺少「tbl_」前綴。