我在数据库中简化了以下关系。
1 User -> n Projects
1 Project -> n Tasks
etc.
所以现在我经常在代码中发现自己以下
// Get the current logged in User
$user = Session::getUser();
$project = $this->projects->findById($project_id);
if ( ! $project->hasOwner($user))
// user does not own the project
随着项目的关系,情况会变得更糟。例如,我必须检查用户是否拥有项目,然后检查任务是否属于项目。
我当时想在这里使用Eager Loading,所以我可以过滤给定的结果。但随后数据库必须加载更多数据,然后经常需要。对吗?
// Get the current logged in User
$user = Session::getUser();
$project = $user->projects()->find($project_id);
if ( ! $project)
// user does not own the project
但即使我这样做,也感觉重复和黑客。我想知道是否有更好的方法来解决这个问题?
答案 0 :(得分:1)
虽然用户可以访问他们的项目,但您需要为将来与其他用户共享项目及其访问类型做好准备。
因此,强烈建议使用project_permission
表。
结构应如下:
id | project_id | grantee_user_id | access_user_id |类型| created_at | updated_at | deleted_at
您将拥有3种类型的权限:
您的权限模型:
class ProjectPermission extends Eloquent {
protected $table = "project_permission";
/*
* Types
*/
const OWNER = 1;
const EDIT = 2;
const READ = 3;
/*
* Scopes
*/
public function scopeOwner($query)
{
return $query->whereType(self::OWNER);
}
public function scopeEdit($query)
{
return $query->whereType(self::EDIT);
}
public function scopeRead($query)
{
return $query->whereType(self::READ);
}
public function project()
{
return $this->belongTo('Project','project_id');
}
}
和项目模型:
class Project extends Eloquent {
...
//Always eager load project permission
public $with = ['permission'];
public function permission()
{
return $this->hasMany('ProjectPermission','project_id');
}
public function scopeUserIsOwner($query,$user_id)
{
return $query->has('permission'=>function($q){
return $q->owner()->where('access_user_id','=',$user_id);
});
}
public function scopeCurrentUserIsOwner($query,$user_id)
{
$user = Session::getUser();
$user_id = $user ? $user->id : 0;
return $query->has('permission'=>function($q){
return $q->owner()->where('access_user_id','=',$user_id);
});
}
/*
* @param int $user_id
* @return boolean
*/
public function hasAccessOwner($user_id)
{
return (bool)$this->permission()->whereType(\ProjectPermission::OWNER)->->whereAccessUserId($user_id)->count();
}
}
理想情况下,您应该只加载用户有权访问的项目。如果需要检查访问权限,hasAccess..
函数将证明是方便的。