当前位置: 首页 > 知识库问答 >
问题:

使用Laravel雄辩模型查询多个表关系

甄伟兆
2023-03-14

我正在尝试使用Laravel雄辩的模型查询多个表,这些模型具有一对一、一对多和多对多的关系。

我有一个forms表,一个brands表,一个users表和一个brand\u groups透视表。

每个表单有一个品牌和一个用户:

forms
  ID
  user_id
  brand_id

品牌没有任何外键:

brands
  ID

用户没有任何外键:

users
  ID

有一个数据透视表可以创建多对多的关系,用于创建拥有许多用户(如品牌成员)的品牌组:

brand_groups
  brand_id
  user_id

我试图通过直接所有权(forms.user\u id)或品牌成员身份获取属于用户的所有表单,通过brand\u group多对多透视表获取用户所属的所有品牌的所有表单。

例如,我们有2个品牌,2个用户,1个用户是1个品牌的成员:

brand(ID: 1)
brand(ID: 2)

user(ID: 1)
user(ID: 2)

brand_group(brand_id: 1, user_id: 1)

form(ID: 1, user_id: 1,    brand_id: null)
form(ID: 2, user_id: null, brand_id: 1)
form(ID: 3, user_id: 2,    brand_id: 1)
form(ID: 4, user_id: 1,    brand_id: 2)

使用Laravel雄辩模型(不是直接的数据库门面调用),我想检索属于用户的所有表单。对于用户(ID: 1)有3种形式:

表单(ID:1)直接用户所有权
表单(ID:2)用户是品牌(ID:1)集团的成员,该集团是表单(ID:2)表单(ID:3)用户是品牌(ID:1)集团的成员,该集团是表单(ID:3)的品牌。

我用雄辩的:人际关系-有很多通过:

“有多通”关系提供了通过中间关系访问远程关系的便捷方式。

我曾经这样尝试过:

class User extends Model
{
    public function forms()
    {
        return Forms::hasManyThrough(
            Form::class,
            BrandGroups::class,
            'brand_id',
            'brand_id',
            'id',
            'form_id',
        )->where('id', $this->id);
    }
}

但我会遇到如下错误:

BadMethodCallException with message 'Call to undefined method App\Models\Form::brand_groups()'

编辑

经过一番挖掘,我终于找到了可以为用户返回所有表单的MySQL代码:

SELECT * FROM `forms`
WHERE EXISTS (
  SELECT `brand_id`, `user_id`
  FROM `brand_groups`
  WHERE `forms`.`brand_id` = `brand_groups`.`brand_id`
    AND `brand_groups`.`user_id` = 1
) OR `forms`.`user_id` = 1

现在我只需要将该查询转换为雄辩的模型关系。

class User extends Authenticatable implements MustVerifyEmail
{
    public function brands()
    {
        return $this
            ->belongsToMany(Brand::class, 'brand_groups')
            ->using(BrandGroups::class)
            ->as('member');
    }

    public function forms()
    {
        return $this->hasMany(Form::class, 'user_id');
    }
}
class Brand extends Model
{
    protected $table = 'brands';

    public function forms()
    {
        return $this->hasMany(Form::class);
    }

    public function members()
    {
        return $this
            ->belongsToMany(User::class, 'brand_groups')
            ->using(BrandGroups::class)
            ->as('member');
    }
}
class Form extends Model
{
    protected $table = 'forms';

    public function owner()
    {
        return $this->belongsTo(User::class);
    }

    public function brand()
    {
        return $this->belongsTo(Brand::class);
    }
}

使现代化

我设法找到一个查询来获取与这样的用户相关的所有表单

class User extends Authenticatable implements MustVerifyEmail
{
    ...

    public function allForms()
    {
        return Form::where(function ($q) {
            $q->whereExists(function ($q) {
                $q->from('brand_groups')
                    ->where('forms.brand_id', DB::raw('brand_groups.brand_id'))
                    ->where('brand_groups.user_id', $this->id);
            })->orWhere('owner_id', $this->id);
        });
    }
}

如何将此转换为直接的用户关系?


共有1个答案

鲁博瀚
2023-03-14

您是否尝试过急切加载用户模型关系?

首先编辑:透视表名称应该是两个表的单数snake_case名称,并且应该按字母顺序排列(brand_user)

接下来,请尝试以下操作:

return User::where(‘id’, $this->id)->with([‘forms’,‘brands.forms’)->get();

这应返回具有直接所有权的表单以及用户品牌及其关联表单

 类似资料:
  • 在我的应用程序中,我更新了从一对多到多对多的关系,我试图找出一种持久化关联功能的方法。 假设我有两个相关的表,例如狗和主人。如果我有一系列的主人,并且我正试图为这些主人获取一份狗的id列表,我应该如何雄辩地做到这一点? 这里也提出了类似的问题:https://laracasts.com/discuss/channels/laravel/getting-many-to-many-related-da

  • 我有一个Laravel后端和一个VueJS前端。 我试图在一个具有hasOne关系的模型上生成一个查询,但只从关系中选择特定的列,做一个sum和一个group By。 null

  • 因此,我在JeffreyWay的屏幕广播中了解到,我可以使用Eloquent从注入到另一个模型的模型中获取相关id。 我正在关注他关于Laravel 5.4的系列报道。 在这里,我有一个用户到帖子的一对多关系。 应用程序/帖子 在我的用户模型中,我有一个发布方法,其中注入了发布模型。发布方法用于创建进入数据库的发布条目。 应用/用户 然后,我在PostsController中有一个存储方法,它在我

  • 我正在使用Laravel和它提供的雄辩的ORM,但我正在努力选择我需要的数据。我有两种型号 我该怎么做?

  • 我使用Laravel为我的应用程序创建API,稍后它将与反应前端集成。我有两张桌子,波斯特 邮政桌 帖子id(主键)帖子标题帖子描述 注释表 注释id(主键)注释文字贴子id(外键) 我需要从帖子表中获取帖子id、帖子标题以及评论表中每个帖子的评论总数 我知道如何为这些数据编写sql查询,但在显示上述数据时遇到了问题。下面是我正在使用的代码。 但这不起作用。我对帖子ID的循环感到困惑,因为它可以获

  • 我是Laravel5.2的新手,正在开发一个遗留系统,对雄辩有点困惑,希望有人能给我代码。 共有3个表格: 卡片类别卡片2类 卡片可以是许多类别的一部分,这些类别保存在cards2cat表中。 cards2cat表的结构如下 id(主键)图像(卡)类别 我想做的是在Cards模型中有一个方法,名为getCardsWithCategors,它返回Cards信息和category表中类别的名称。 ca