我正在使用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));
在此先感谢您的帮助,我已经研究了一段时间,但找不到优雅的解决方案。
答案 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();