我有User
,Role
& Page
设置,所有这些都具有多对多关系,并且透视表以通常的方式设置(role_user
,page_role
),以及将模型附加到枢轴的雄辩方法表。
我的想法是允许用户拥有多个角色,并且许多角色都可以访问页面。
但是现在我想返回一个集合,其中我有我的用户详细信息,然后是他们允许访问的页面。
我最接近的是:
return User::find( Auth::user()->id )->with('roles.pages')->first()->roles;
现在,它返回用户拥有的每个角色,以及角色可以访问的每个页面。哪个是正确的,但我在pages
部分有重复。
我如何只获取用户无法复制的页面列表?
干杯
答案 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;
Auth::id()
代替Auth::user()->id
(适用于Laravel ver 4.1.25+)以避免冗余查询find()
和first()
是执行查询的方法,因此您刚刚返回id = Auth::user()->id
的用户,稍后您将获取另一个来first()
的用户来自用户表.. User::whatever
,而是使用Auth::user()
。所以建议解决方案的代码如下所示:
Auth::user()->pages; // collection of Page models with unique entries