阅读该答案让您步入正轨: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;
- 使用
Auth::id() 而不是Auth::user()->id(对于 Laravel 4.1.25+ 版本)以避免冗余查询
-
find() 和 first() 是执行查询的方法,因此您只需返回 id = Auth::user()->id 的用户,稍后您会从 users 表中获取另一个用户 first()。
- 认证用户不需要使用
User::whatever,而是使用Auth::user()。
所以建议解决方案的代码如下所示:
Auth::user()->pages; // collection of Page models with unique entries