【问题标题】:Eloquent: Get pages based on user roleEloquent:根据用户角色获取页面
【发布时间】:2014-08-18 23:18:41
【问题描述】:

我有一个UserRolePage 设置,都具有多对多关系和以通常方式设置的数据透视表(role_userpage_role),以及雄辩的将模型附加到数据透视表的方法。

我的想法是让一个用户拥有多个角色,一个页面可以被多个角色访问。

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

我得到的最接近的是:

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

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

我将如何只获取用户能够访问而没有重复的页面列表?

干杯

【问题讨论】:

    标签: sql laravel eloquent


    【解决方案1】:

    阅读该答案让您步入正轨: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;
    }
    

    还有一件事:为了简单起见,我对表和列名称进行了硬编码,但在现实生活中,我建议您依赖关系及其 getter,例如:$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 4.1.25+ 版本)以避免冗余查询
    2. find()first() 是执行查询的方法,因此您只需返回 id = Auth::user()->id 的用户,稍后您会从 users 表中获取另一个用户 first()
    3. 认证用户不需要使用User::whatever,而是使用Auth::user()

    所以建议解决方案的代码如下所示:

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

    【讨论】:

    • 为抬头欢呼真棒,效果很好:) 编辑:直接从User 模型内部加载Page 模型是否正确?
    • 正确是什么意思?这不是您需要的吗:) 它只是调整框架提供的内容以满足您的需求。
    • 是否可以向我展示上面应该如何正确实施?此外,如果用户未登录,我需要检查是否有任何页面具有“访客”角色。逻辑在这个粘贴中工作,但似乎不是“最好”的方式......laravel.io/bin/QqlnD
    • 检查编辑,你有关于User模型的一切。这是给你的粘贴laravel.io/bin/mlqzq
    • 啊,我明白了!另一件事,当然“用户”永远不会与页面有关系,所以它总是会执行“loadPages()”方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 2014-10-22
    • 2018-08-20
    相关资源
    最近更新 更多