2011-08-04 1471 views
5

Estoy usando Yii y tengo 3 tablas: usuarios, dispositivos con una tabla users_devices (user_id, device_id) para definir la relación MANY_MANY entre ellos.Yii encuentra modelos a través de many_many relación

Lo que estoy buscando es el método más simple para encontrar un dispositivo desde su id (devices.id) que pertenece a un usuario específico (users.id) a través de ActiveRecord.

El escenario es una API REST que está buscando un dispositivo, pero quiero verificar que el dispositivo sea propiedad del usuario por razones de seguridad.

Algo como esto es la idea:

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

Gracias de antemano por cualquier ayuda, he estado investigando esto durante un tiempo y no puedo encontrar una solución elegante.

+0

¿Los dispositivos de usuario tienen user_id y device_id como claves primarias (compuestas)? Es así, no olvide sobrescribir prmaryKey() como lo hacen [aquí] (http://learnyii.blogspot.com/2010/12/yii-on-many- many-relations.html). Y podría hacer un hallazgo en esa tabla utilizando su modelo personalizado para identificar la relación usuario-dispositivo (o la falta de uno). – hobs

+0

Usted quiso decir que MANY_MANY no tiene HAS_MANY. – hobs

+0

@Hobs, tienes razón. –

Respuesta

7

dieron un poco de ayuda en los foros de Yii, lo que me llevó a la figura hacia fuera a mí mismo:

$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

¿Tienes que usar AR?

siempre prefiero usar el query builder cuando se trata de declaraciones complejas ...

es decir

$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

Creo que tengo que usar el generador de consultas, la depuración sin fin cuando se trata de una consulta compleja utilizando los criterios de Yii. Gracias –

2

Tome dos.

en 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 
     ); 
    } 

a continuación para encontrar si el dispositivo solicitado es propiedad del usuario que solicita:

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

Parece que esto iba a funcionar, pero de manera ineficiente recuperar una gran cantidad de innecesaria Registros de usuario, ya que ya sabe quién es el usuario y es probable que ya tenga su Registro activo. Para evitar esto innefficiency, el libro Yu Desarrollo ágil utiliza SQL prima para consultas relación M2M dentro del modelo de matriz (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; 
} 

Solía ​​DeviceDevices en lugar de por el nombre del modelo (igualmente para device El nombre de las mesa). Refactor si corta y pega. Del mismo modo para User. Del mismo modo, falta el prefijo "tbl_".

Cuestiones relacionadas