Yii通过many_many关系找到模型

时间:2011-08-04 18:15:04

标签: php mysql activerecord many-to-many yii

我正在使用Yii并拥有3个表:用户,带有users_devices表(user_id,device_id)的设备,用于定义它们之间的MANY_MANY关系。

我正在寻找的是通过ActiveRecord从其id(devices.id)中找到属于特定用户(users.id)的设备的最简单方法。

方案是REST API正在查询设备,但出于安全原因,我想验证设备是否由用户拥有。

这样的想法是这样的:

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

在此先感谢您的帮助,我已经研究了一段时间,但找不到优雅的解决方案。

3 个答案:

答案 0 :(得分: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 :(得分: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。为了避免这种不足,Yii Agile Development书籍在父模型(Device.php)中使用原始SQL进行M2M关系查询:

// "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_”前缀。

答案 2 :(得分: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();
相关问题