はじめに
こんばんは。
ちょうあっさりした、かつ、基本的なものですが、備忘録のために残しときます。
タイトルの通り、 hasMany関係のテーブルから1件以上のデータが登録あるものだけ取得する方法です。
さらに、そのテーブルのデータは 登録日降順で取得するものとします。
やってみた
以下みたいなテーブルがあるとします。
CREATE TABLE `categories` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PrimaryKey', `name` varchar(256) NOT NULL DEFAULT '' COMMENT 'カテゴリ名', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '登録日', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日', PRIMARY KEY (`id`), KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'カテゴリ管理テーブル'; CREATE TABLE `items` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PrimaryKey', `category_id` int(11) unsigned NOT NULL COMMENT 'カテゴリID', `name` varchar(256) NOT NULL DEFAULT '' COMMENT 'アイテム名', `price` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '価格', `delivery_cost` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '配送料', `stock` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '在庫', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '登録日', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日', PRIMARY KEY (`id`), KEY `userId` (`name`), CONSTRAINT `items_fk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'アイテム管理テーブル';
Eloquentは以下みたいな感じ?
<?php class EloquentCategory extends Model { protected $table = 'categories'; /** * @return HasMany */ public function items(): HasMany { return $this->hasMany(EloquentItem::class); } } class EloquentItem extends Model { protected $table = 'items'; /** * @return BelongsTo */ public function area(): BelongsTo { return $this->belongsTo(EloquentCategory::class); } }
Itemが1件以上登録があるCategoryを取得する方法は以下
<?php /** * @return array */ public function findCategories(): array { return EloquentCategory::query() ->with(['items' => function (HasMany $query): void { $query->orderBy('created_at', 'DESC'); }]) ->orderBy('id', 'asc') ->get()->filter(function ($item) { return ($item->items->count() >= 1); })->toArray(); }
これで、アイテムが1件以上登録のあるカテゴリのcollectionが取得できます。
withの小技と、collectionのfilterを組み合わせただけなんですが、こういうところって知ってないと使えないですよね。
調べるまでは泥臭く foreach で再現やる感じかな?と想像してました。
終わりに
今日はとりあえずこんな感じです。
12月チャレンジのために来週からは仕込み期間です。
がんばります。