Laravelをフレームワークとして使う1つの魅力は、Collectionにあります。Eloquentでデータベースから取得した後のレコード処理がとてもエレガントにわかりやく書くことができます。というものの、Laravelのマニュアルに出てくるCollectionの例は配列ベースをcollect()したものばかりで物足りません。ということで、ここでCollectionの紹介を兼ねてDBからの取得にCollectionのメソッドを適用する例を掲載します。

準備

まずは、DBレコード取得ための準備から。

ここでで作成したLaravelのプロジェクトをもとにします。

そこで使用されている、DBテーブルにある項目を追加したいので、まずはmigrationを作成します。

$ php artisan make:migration add_new_fields_to_users_table --table=users

Created Migration: 2021_05_30_213829_add_new_fields_to_users_table

以下のようにusersのDBテーブルにbirth_date、つまり誕生日の項目を追加します。


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddNewFieldsToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->date('birth_date')->nullable()->after('remember_token');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('birth_date');
        });
    }
}

そして、migrationを実行してDBに項目を追加します。

$ php artisan migrate

Migrating: 2021_05_30_213829_add_new_fields_to_users_table
Migrated:  2021_05_30_213829_add_new_fields_to_users_table (0.09 seconds)

次に、factoryで自動データ作成のために項目を追加します。

...
$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name(),
        'email' => $faker->unique()->safeEmail(),
        'email_verified_at' => now(),
        'password' => Hash::make('password'),
        'remember_token' => Str::random(10),
        'birth_date' => $faker->date(),
    ];
});

tinkerでdate_birthを追加したusersのレコードを3つ作成します。

>>> User::truncate()

=> Illuminate\Database\Eloquent\Builder {#3302}

>>> factory(\App\User::class, 3)->create()

=> Illuminate\Database\Eloquent\Collection {#4258
     all: [
       App\User {#4254
         name: "坂本 充",
         email: "nishida@example.net",
         email_verified_at: "2021-05-30 21:55:14",
         #password: "$2y$10$snEjTmJvBDu3uxd1bz0QDupihJA3zjvEH5J0pm/aLHG4UvpSfJe/q",
         #remember_token: "j8hPjp8ob7",
         birth_date: "1997-03-02",
         updated_at: "2021-05-30 21:55:14",
         created_at: "2021-05-30 21:55:14",
         id: 1,
       },
       App\User {#4252
         name: "藤本 和也",
         email: "yoshida.kana@example.com",
         email_verified_at: "2021-05-30 21:55:14",
         #password: "$2y$10$QiozldxVUo3LLj347mqHxeoDh5TEcjddDwc6vN8Pv5b4kPgPUgjri",
         #remember_token: "frW94QFFZh",
         birth_date: "2005-10-03",
         updated_at: "2021-05-30 21:55:14",
         created_at: "2021-05-30 21:55:14",
         id: 2,
       },
       App\User {#4251
         name: "近藤 知実",
         email: "atsushi.ito@example.net",
         email_verified_at: "2021-05-30 21:55:14",
         #password: "$2y$10$A7xldQvOiCfUOyNS57EEYu2/s77a70BPmGoOjzDSgTmveeRlcAD8.",
         #remember_token: "qOFWQFb5ER",
         birth_date: "1972-09-14",
         updated_at: "2021-05-30 21:55:14",
         created_at: "2021-05-30 21:55:14",
         id: 3,
       },
     ],
   }

Collectionから1つの値を返すメソッド

DBレコードが揃ったところで、CollectionのメソッドをEloquentで取得したCollectionに適用です。
今回は、1つの値だけを返す簡単なメソッドの紹介をします。

まずは、Collectionのレコード数が必要なら以下のようにcount()をチェーンして返すことできます。

>>> User::all()->count()

=> 3

>>> User::where('id', '>', 1)->get()->count()

=> 2

ここDB処理でも同じことできますけれど、それに関しては「Eloquentでカウントするときの注意」で説明しています。

次の例ではmax()min()はそれぞれ最大値と最小値を返してくれます。この手の集計関数は他にも、avg()median()reduce()sum()もあります。

>>> User::all()->max('birth_date')

=> "2005-10-03"

>>> User::all()->min('birth_date')

=> "1972-09-14"

次の例はブーリアン値を返すメソッドです。

contains()は、含んでいるならブーリアン値のtrueを返します。

>>> User::all()->contains(function($item) {
        return $item->birth_date === '2005-10-03';
    })

=> true

また、EloquentのモデルのUserのプライマリキーを引数として渡すこともできます。これは通常のCollectionには適用不可でEloquentのCollectionのみに使用できるメソッドです。

>>> User::all()->contains(3)

=> true

>>> User::all()->contains(4)

=> false

ブーリアン値を返すものには以下の空判定のメソッドもありますね。

>>> User::all()->isEmpty()

=> false

>>> User::all()->isNotEmpty()

=> true

次の例はオブジェクトを返すメソッドです。

以下のように、最初と最後のレコードのオブジェクトを返すことが可能です。

>>> User::all()->first()

=> App\User {#4254
     id: 1,
     name: "坂本 充",
     email: "nishida@example.net",
     email_verified_at: "2021-05-30 21:55:14",
     #password: "$2y$10$snEjTmJvBDu3uxd1bz0QDupihJA3zjvEH5J0pm/aLHG4UvpSfJe/q",
     #remember_token: "j8hPjp8ob7",
     birth_date: "1997-03-02",
     created_at: "2021-05-30 21:55:14",
     updated_at: "2021-05-30 21:55:14",
   }

>>> User::all()->last()

=> App\User {#4260
     id: 3,
     name: "近藤 知実",
     email: "atsushi.ito@example.net",
     email_verified_at: "2021-05-30 21:55:14",
     #password: "$2y$10$A7xldQvOiCfUOyNS57EEYu2/s77a70BPmGoOjzDSgTmveeRlcAD8.",
     #remember_token: "qOFWQFb5ER",
     birth_date: "1972-09-14",
     created_at: "2021-05-30 21:55:14",
     updated_at: "2021-05-30 21:55:14",
   }

次回は、Collectionを返すメソッドを紹介します。

By khino