gpt4 book ai didi

php - "Three way"使用 Eloquent 的多对多关系

转载 作者:行者123 更新时间:2023-11-30 01:32:29 24 4
gpt4 key购买 nike

我有一个简单的数据库设置:用户、组、页面 - 每个都是多对多。见图:http://i.imgur.com/oFVsniH.png

现在我有一个可变的用户 ID ($id),通过这个我想获取用户有权访问的页面列表,因为它在所有表上都是多对多的。

我已经像这样设置了我的主要模型:

class User extends Eloquent {
protected $table = 'ssms_users';

public function groups()
{
return $this->belongsToMany('Group', 'ssms_groups_users', 'user_id','group_id');
}

}
class Group extends Eloquent {
protected $table = 'ssms_groups';

public function users()
{
return $this->belongsToMany('User', 'ssms_groups_users', 'user_id','group_id');
}

public function pages()
{
return $this->belongsToMany('Page', 'ssms_groups_pages', 'group_id','page_id');
}

}
class Page extends Eloquent {
protected $table = 'ssms_pages';

public function groups()
{
return $this->belongsToMany('Group', 'ssms_groups_pages', 'group_id','page_id');
}

}

我可以通过简单地执行以下操作来获取用户所属的组:

User::with('groups')->first(); // just the first user for now

但是我完全不知道如何通过一个查询获取用户可以(明确)访问的页面?

我相信 SQL 会是这样的:

select DISTINCT GP.page_id
from GroupUser GU
join GroupPage GP on GU.group_id = GP.group_id
where GU.user_id = $id

有人可以帮忙吗?

谢谢

最佳答案

TL;博士:下面的 MyCollection 类中的 fetchAll 方法完成这项工作。只需调用 fetchAll($user->groups, 'pages');

<小时/>

好吧,假设您成功加载了数据(这应该通过急切加载来完成,如其他答案中所述),您应该循环遍历 GroupUser 具有,然后循环遍历其 Page 并将其添加到新集合中。因为我已经遇到了这个问题,所以我认为简单地扩展 Laravel 自己的 Collection 类并添加一个通用方法来做到这一点会更容易。

为了简单起见,只需创建一个 app/libraries 文件夹并将其添加到 composer.jsonautoload -> classmap 下,它将负责为我们加载类。然后将扩展的 Collection 类放入该文件夹中。

app/libraries/MyCollection.php

use Illuminate\Database\Eloquent\Collection as IlluminateCollection;

class MyCollection extends IlluminateCollection {

public function fetchAll($allProps, &$newCollection = null) {
$allProps = explode('.', $allProps);
$curProp = array_shift($allProps);

// If this is the initial call, $newCollection should most likely be
// null and we'll have to instantiate it here
if ($newCollection === null) {
$newCollection = new self();
}

if (count($allProps) === 0) {

// If this is the last property we want, then do gather it, checking
// for duplicates using the model's key
foreach ($this as $item) {
foreach ($item->$curProp as $prop) {
if (! $newCollection->contains($prop->getKey())) {
$newCollection->push($prop);
}
}
}
} else {

// If we do have nested properties to gather, then pass we do it
// recursively, passing the $newCollection object by reference
foreach ($this as $item) {
foreach ($item->$curProp as $prop) {
static::make($prop)->fetchAll(implode('.', $allProps), $newCollection);
}
}
}

return $newCollection;
}
}

但是,为了确保您的模型将使用此类,而不是原始的 Illuminate\Database\Eloquent\Collection,您必须创建一个基本模型,从中您可以扩展所有模型,并覆盖 newCollection 方法。

app/models/BaseModel.php

abstract class BaseModel extends Eloquent {

public function newCollection(array $models = array()) {
return new MyCollection($models);
}

}

不要忘记,您的模型现在应该扩展 BaseModel,而不是 Eloquent。完成所有这些后,要获取所有 UserPage(只有其 ID),请执行以下操作:

$user = User::with(array('groups', 'groups.pages'))
->find($id);

$pages = $user->groups->fetchAll('pages');

关于php - "Three way"使用 Eloquent 的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17300086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com