限制从 Laravel Eloquent 中连接的表/模型返回的字段

Posted

技术标签:

【中文标题】限制从 Laravel Eloquent 中连接的表/模型返回的字段【英文标题】:Limit fields returned from joined tables/models in Laravel Eloquent 【发布时间】:2021-11-18 06:06:19 【问题描述】:

我正在使用 Laravel(在 Jetstream/Inertia 和 VueJS 中),在我的控制器中,我正在查询三个表:usersstationsshiftsshifts 是我的主表,它具有 users 表 (user_id) 和 stations 表 (station_id) 的外键。

在我的控制器中,我使用以下查询来获取所有数据。

$monthShifts = Shift::where(DB::raw('MONTH(date)'), $queryMonth)
    ->where(DB::raw('YEAR(date)'), $queryYear)
    ->with('user', 'station')
    ->get();

这让我得到了我需要的以下格式:

$shifts = [
    [0] => Array
        (
            [id] => 1
            [date] => 2021-09-15
            [user_id] => 3
            [station_id] => 1
            [am_pm] => pm
            [user] => Array
                (
                    [id] => 3
                    [name] => Andy Ryan
                    [type] => suppression
                    [email] => emann@mydomain.com
                )

            [station] => Array
                (
                    [id] => 1
                    [station_number] => 12
                    [station_name] => Main
                )
        )

    [1] => Array
        (
            [id] => 6
            [date] => 2021-09-12
            [user_id] => 6
            [station_id] => 2
            [am_pm] => pm
            [created_at] => 2021-09-15T23:05:27.000000Z
            [updated_at] => 2021-09-15T23:05:27.000000Z
            [user] => Array
                (
                    [id] => 6
                    [name] => Mohammed Veum
                    [type] => suppression
                    [email] => hhuel@mydomain.com
                )

            [station] => Array
                (
                    [id] => 2
                    [station_number] => 13
                    [station_name] => Secondary
                )

        )

    [2] => Array
        (
            [id] => 7
            [date] => 2021-09-11
            [user_id] => 7
            [station_id] => 2
            [am_pm] => pm
            [created_at] => 2021-09-15T23:05:27.000000Z
            [updated_at] => 2021-09-15T23:05:27.000000Z
            [user] => Array
                (
                    [id] => 7
                    [name] => Santa Wolf
                    [type] => support
                    [email] => mbashirian@mydomain.com
                )

            [station] => Array
                (
                    [id] => 2
                    [station_number] => 13
                    [station_name] => Secondary
                )

        )

    [3] => Array
        (
            [id] => 9
            [date] => 2021-09-05
            [user_id] => 6
            [station_id] => 2
            [am_pm] => pm
            [created_at] => 2021-09-15T23:05:27.000000Z
            [updated_at] => 2021-09-15T23:05:27.000000Z
            [user] => Array
                (
                    [id] => 6
                    [name] => Mohammed Veum
                    [type] => suppression
                    [email] => hhuel@mydomain.com
                )

            [station] => Array
                (
                    [id] => 2
                    [station_number] => 13
                    [station_name] => Secondary
        )

    [4] => Array
        (
            [id] => 10
            [date] => 2021-09-02
            [user_id] => 7
            [station_id] => 2
            [am_pm] => pm
            [created_at] => 2021-09-15T23:05:27.000000Z
            [updated_at] => 2021-09-15T23:05:27.000000Z
            [user] => Array
                (
                    [id] => 7
                    [name] => Santa Wolf
                    [type] => support
                    [email] => mbashirian@mydomain.com

            [station] => Array
                (
                    [id] => 2
                    [station_number] => 13
                    [station_name] => Secondary
                )

        )

    [5] => Array
        (
            [id] => 13
            [date] => 2021-09-02
            [user_id] => 3
            [station_id] => 2
            [am_pm] => pm
            [created_at] => 2021-09-15T23:05:27.000000Z
            [updated_at] => 2021-09-15T23:05:27.000000Z
            [user] => Array
                (
                    [id] => 3
                    [name] => Andy Ryan
                    [type] => suppression
                    [email] => emann@mydomain.com
                )

            [station] => Array
                (
                    [id] => 2
                    [station_number] => 13
                    [station_name] => Secondary
                )
        )
]

但是,我想做的是只从所有三个中获取特定字段:

    am_pm, id 来自顶层 (shift) station_number 来自station nametype 来自 user

在直接的 SQL 中,我会这样写:

select s.id, s.date, s.am_pm, u.name, u.type, st.station_number
from shifts s inner join users u on s.user_id = u.id
inner join stations st on s.station_id = st.id
where MONTH(date) = month
and year(date) = year

如何将项目限制在这些字段中,并将它们展平?如果我不想包含 stationuser 对象,我可以这样做来限制 shift 数据:

         $monthShifts = Shift::where(DB::raw('MONTH(date)'), $queryMonth)
             ->where(DB::raw('YEAR(date)'), $queryYear)
             ->get(['date', 'am_pm', 'id'])
             ->groupBy(['date', 'am_pm']);

然后我丢失了我需要的其他数据(userstation),以及station_number 的分组。

【问题讨论】:

【参考方案1】:
 ->with(['user'=>function ($query) 
                $query->select('id', 'name', 'type');
              , 
 'station'=>function ($query) 
          $query->select('station_number');
      ])->get(['id','am_pm','user_id','station_id'])

你必须在 get() 中包含 shifts 表中的 'user_id' 和 'station_id' 才能以这种方式获取关系数据

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

使用 pluck 方法将解决您的问题

https://laravel.com/docs/8.x/collections#method-pluck

【讨论】:

以上是关于限制从 Laravel Eloquent 中连接的表/模型返回的字段的主要内容,如果未能解决你的问题,请参考以下文章

使用 laravel eloquent 从两个连接表中获取数据

Laravel Eloquent 在与其他表连接后从关系中选择字段

Laravel Eloquent:如何从连接表中仅获取某些列

在 Laravel Eloquent 中连接表值

Laravel 5.3 Eloquent 交易和外键限制

用 Laravel/Eloquent 为 Yajra DataTables 编写连接查询的慢 MySQL