2015-03-02 123 views
1

我在數據庫中簡化了以下關係。什麼是檢查用戶是否有權訪問實體的最佳方法

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 

但即使我這樣做,它感覺重複和哈克。我想知道是否有更好的方法來解決這個問題?

回答

1

雖然用戶可以訪問他們的項目,但您需要爲將來與其他用戶共享項目及其訪問類型做出規定。

因此,強烈建議使用project_permission表。

結構應該如下:

id | project_id | grantee_user_id | access_user_id |鍵入| created_at | updated_at | deleted_at

您將有3種類型的權限:

  1. 所有者 - 完全權限
  2. 編輯訪問
  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'); 
    } 

} 

和項目m odel:

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..功能將證明是方便的。

相關問題