Eloquent:根据用户角色获取页面

时间:2014-06-27 18:36:12

标签: sql laravel eloquent

我有UserRole& Page设置,所有这些都具有多对多关系,并且透视表以通常的方式设置(role_userpage_role),以及将模型附加到枢轴的雄辩方法表。

我的想法是允许用户拥有多个角色,并且许多角色都可以访问页面。

但是现在我想返回一个集合,其中我有我的用户详细信息,然后是他们允许访问的页面。

我最接近的是:

return User::find( Auth::user()->id )->with('roles.pages')->first()->roles;

现在,它返回用户拥有的每个角色,以及角色可以访问的每个页面。哪个是正确的,但我在pages部分有重复。

我如何只获取用户无法复制的页面列表?

干杯

1 个答案:

答案 0 :(得分:2)

阅读该答案,让您走上正轨:HasManyThrough with one-to-many relationship

仅针对您的设置,您需要调整查询 - 连接2个数据透视表(并确保它们代表实际数据,即没有引用非现有模型的行):

// User model

// accessor so you can access it like any relation: $user->pages;
public function getPagesAttribute()
{
    if ( ! array_key_exists('pages', $this->relations)) $this->loadPages();

    return $this->getRelation('pages');
}

// here you load the pages and set the collection as a relation
protected function loadPages()
{
    $pages = Page::join('page_role as pr', 'pr.page_id', '=', 'pages.id')
           ->join('role_user as ru', 'ru.role_id', '=', 'pr.role_id')
           ->where('ru.user_id', $this->id)
           ->distinct()
           ->get(['pages.*', 'user_id']);

    $hasMany = new Illuminate\Database\Eloquent\Relations\HasMany(Page::query(), $this, 'user_id', 'id');

    $hasMany->matchMany(array($this), $pages, 'pages');

    return $this;
}

还有一件事:为了简单起见,我对表格和列名称进行了硬编码,但在现实生活中,我建议您依赖关系及其获取者,例如:$relation->getTable()$relation->getForeignKey()等。


现在建议你的代码:

return User::find( // 2. query to get the same user
     Auth::user()->id  // 1. query to get the user and his id
   )->with('roles.pages')
     ->first() // 3. query to get ANOTHER user (or the same, luckily..)
     ->roles;
  1. 使用Auth::id()代替Auth::user()->id(适用于Laravel ver 4.1.25+)以避免冗余查询
  2. find()first()是执行查询的方法,因此您刚刚返回id = Auth::user()->id的用户,稍后您将获取另一个来first()的用户来自用户表..
  3. 您不需要对经过身份验证的用户使用User::whatever,而是使用Auth::user()
  4. 所以建议解决方案的代码如下所示:

    Auth::user()->pages; // collection of Page models with unique entries