概要
LaravelのEloquentでデータを取得した際、get
メソッドを使用する際、コレクション形式でデータが取得できます。
getメソッドで取得したデータには、キーととコレクション値が含まれます。
しかし、whereIn
やwhereNotIn
節を使用する場合などで、コレクション値のみを取得したい場合、pluck
メソッドを使用することで、直接コレクション値を取得できるようになります。
例
Laravelで通知の未読数を取得する際、既読の通知レコードを取得し、通知一覧から既読ではない通知を取得することで、通知の未読数を取得しています。
例で使用しているDB定義
通知テーブル(trn_notice)
No | 論理名 | 物理名 | データ型 |
---|---|---|---|
1 | ID | id | uuid |
2 | 作成日時 | created_at | timestanp |
3 | 更新日時 | updated_at | timestanp |
4 | 削除日時 | deleted_at | timestanp |
5 | 利用者マスタID | user_id | uuid |
6 | 配信日時 | stream_date | timestanp |
7 | 通知タイトル | notice_title | varchar(256) |
8 | 通知内容 | notice_contents | text |
通知既読テーブル(trn_notice_read)
No | 論理名 | 物理名 | データ型 |
---|---|---|---|
1 | ID | id | uuid |
2 | 作成日時 | created_at | timestanp |
3 | 更新日時 | updated_at | timestanp |
4 | 削除日時 | deleted_at | timestanp |
5 | 利用者マスタID | user_id | uuid |
6 | 既読通知ID | read_notice_id | uuid |
pluck
メソッドを使用せずに、処理を記載すると以下のようになります。
/**
* 通知の未読数を取得する
* @return int $unread 未読件数
*/
public function getUnread() {
// JWTからログインしている利用者IDを取得
$userId = Auth::id();
// 既読済みの通知ID
$readNoticeId = [];
try {
// 既読済みの通知を取得
$reads = TrnNoticeRead::where('user_id', '=', $userId)
->get();
// 既読の通知IDが存在する場合ループし、通知IDを配列に保持
if (!$reads->isEmpty()) {
foreach($reads as $read) {
$readNoticeId[] = $read->read_notice_id;
}
}
// 未読の通知数を取得
$unread = TrnNotice::where('user_id', '=', $userId)
// 既読ではない通知
->whereNotIn('id', $readNoticeId)
->orderBy('stream_date', 'desc')
->count();
return $unread;
} catch (Exception $exception) {
\Log::error($exception);
throw $exception;
}
}
既読済みの通知をget
メソッドで取得した場合、以下のようにデータが取得できます。
[
{
"id": 85f4736b-a909-a63a-9428-79805804f248,
"created_at": "2023-01-20 12:00:00.000",
"updated_at": "2023-01-20 12:00:00.000",
"deleted_at": null,
"user_id": c56328f6-be77-9dd5-2f72-a5b8a136e654,
"read_notice_id": ffeb35c4-311f-c52e-86ba-e79225e2811a,
}, {
"id": bc65cc1b-91dc-7fde-5afc-9d1450d63407,
"created_at": "2023-01-20 12:00:00.000",
"updated_at": "2023-01-20 12:00:00.000",
"deleted_at": null,
"user_id": b796948d-3a3e-8d89-f2a9-31845b15e1ff,
"read_notice_id": 674ad489-10a6-e6fd-9c8f-6b738f744934,
}
]
しかし、whereNotIn節を使用するには、[ffeb35c4-311f-c52e-86ba-e79225e2811a, 674ad489-10a6-e6fd-9c8f-6b738f744934]
形式にする必要があるため、foreachで配列に挿入する処理を行う必要があります。
foreachで取得したコレクションをループさせ、別配列にプッシュするとなると、通知件数が多くなるにつれてどんどん処理時間が増えていってしまいます。
そこで、pluckメソッドを使用することで、配列に既読した通知のIDが入った状態で取得できるようになります。
/**
* 通知の未読数を取得する
* @return int $unread 未読件数
*/
public function getUnread() {
// JWTからログインしている利用者IDを取得
$userId = Auth::id();
try {
// 既読済みの通知を取得
$reads = TrnNoticeRead::where('user_id', '=', $userId)
// コレクション値のみを返す
->pluck('read_notice_id');
// 未読の通知数を取得
$unread = TrnNotice::where('user_id', '=', $userId)
// 既読ではない通知
->whereNotIn('id', $readNoticeId)
->orderBy('stream_date', 'desc')
->count();
return $unread;
} catch (Exception $exception) {
\Log::error($exception);
throw $exception;
}
}
pluckメソッドを使用することで、クエリで処理するため、通知件数が増えても高速で未読数を取得することができるようになります。