見出し画像

[laravel8] Eloquentとアクティブレコードパターン

Eloquentモデル

まず、以下のファイルを見てみましょう。

app/Models/User.php

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
   use HasFactory, Notifiable;

   /**
    * The attributes that are mass assignable.
    *
    * @var array
    */
   protected $fillable = [
       'name',
       'email',
       'password',
   ];

   /**
    * The attributes that should be hidden for arrays.
    *
    * @var array
    */
   protected $hidden = [
       'password',
       'remember_token',
   ];

   /**
    * The attributes that should be cast to native types.
    *
    * @var array
    */
   protected $casts = [
       'email_verified_at' => 'datetime',
   ];
} 

 ​LaravelではこれをEloquentモデルと呼びます。

簡単に言うとデータベースとやりとりをするためのクラスになります。開発を進めるにつれて必要なデータベースのテーブルを追加していくことになるかと思いますが、そのテーブルの一つ一つにEloquentモデルを作成していくことになります。

上のUserクラスはusersテーブルに対応したEloquentモデルです。(通常はテーブル名は名詞の複数形、モデル名は単数形)

そしてUserインスタンスはusersテーブルのレコード(行)にマップされます。 これをアクティブレコードパターンと呼ばれるデザインパターンの一つです。

Active Recordはデータベースからデータを読み出すためのアプローチである。データベーステーブルあるいはビューの1行が1つのクラスにラップされ、オブジェクトのインスタンスがそのデータベースの1つの行に結合される。

実際にレコード(行)を作成

Laravelに標準搭載されている対話シェルで、データベースなどをコマンドを使って操作できるTinkerを使用していきます。

まずは次のコマンドでTinkerに入ります。

$php artisan tinker
Psy Shell v0.10.8 (PHP 8.0.3 — cli) by Justin Hileman
>>> ​

次にユーザーのインスタンスを作成します。

>>> $user = new App\Models\User;
=> App\Models\User {#3341}
>>> 
App\Models\User

としているのは、Userクラスを見るとnamespaceがApp\Modelsになり、UserクラスのパスがApp\Models\Userになるためです。

ただTinkerの場合は以下のようにUserだけでも(App\Models\Userのパスではなくても)Tinkerが勝手に判断してくれてUserのインスタンスを作成することも可能です。

>>> $user = new User;
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
=> App\Models\User {#3350}
>>> 

Laravelのマイグレーションで作られるusersテーブルの構造を見てみましょう。

スクリーンショット 2021-05-06 20.15.51

最低限必要なデータは name,email,password。これらをTinkerを使用し作成していきます。

>>> $user = new User;
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
=> App\Models\User {#3350}
>>> $user->name = 'tomocito';
=> "tomocito"
>>> $user->email = 'test@test.com';
=> "test@test.com"
>>> $user->password = bcrypt('password');
=> "$2y$10$CoHE9v5oHTSMDmHvXQkE5evRzRPvrur6iu5Hy/Mg661PUCNc.i7Du"
>>> $user->save();
=> true
>>> 

nameとemailは問題ないですが、パスワードはデータベース内でそのままのテキストでは保存しません。必ず暗号化して保存します。Laravelではbcryptという暗号化する関数が準備されているので、ここではそれを使用しました。そして最後に save()でデータベースへ保存します。

データベースを確認すると今入力したデータが保存されていることがわかります。created_atとupdated_atは自動的に作成されています。

スクリーンショット 2021-05-06 20.23.50

データベースに作成できたので、Tinkerに戻ります。

$userには今保存したデータが残っています。

>>> $user;
=> App\Models\User {#3350
    name: "tomocito",
    email: "test@test.com",
    #password: "$2y$10$CoHE9v5oHTSMDmHvXQkE5evRzRPvrur6iu5Hy/Mg661PUCNc.i7Du",
    updated_at: "2021-05-06 11:19:46",
    created_at: "2021-05-06 11:19:46",
    id: 1,
  }
>>> 

もちろん、それぞれのプロパティにもアクセスできます。

>>> $user->name;
=> "tomocito"
>>> $user->password;
=> "$2y$10$CoHE9v5oHTSMDmHvXQkE5evRzRPvrur6iu5Hy/Mg661PUCNc.i7Du"
>>> 

データを書き換えて遊んでみたりもできますね。

>>> $user->name = 'tomo2cito';
=> "tomo2cito"
>>> $user->save();
=> true
>>>

テーブルを見てみると

スクリーンショット 2021-05-06 20.28.18

変更されているのがわかりますね。

データを取得してTinkerで少し遊ぶためにUserをもう一人増やします。

>>> $user = new User;
=> App\Models\User {#4135}
>>> $user->name = 'tanaka';
=> "tanaka"
>>> $user->email = 'tanaka@test.com';
=> "tanaka@test.com"
>>> $user->password = bcrypt('tanakapass');
=> "$2y$10$6gVHsREKsZ76DZlorxjxfeSqJ.9X9paoPEBZiVS8x63Q2LbCmQQwW"
>>> $user->save();
=> true
>>>

スクリーンショット 2021-05-06 20.31.47

データの取得

usersテーブルに id=2 で追加したtanakaさんを取得してみましょう。

>>> $user = User::find(2);
=> App\Models\User {#4069
    id: 2,
    name: "tanaka",
    email: "tanaka@test.com",
    email_verified_at: null,
    #password: "$2y$10$6gVHsREKsZ76DZlorxjxfeSqJ.9X9paoPEBZiVS8x63Q2LbCmQQwW",
    #remember_token: null,
    created_at: "2021-05-06 11:31:16",
    updated_at: "2021-05-06 11:31:16",
  }
>>> 

Userモデルのfindメソッドを使い簡単に取得することができます。

しかし、存在しないidを探した場合はどうなるでしょうか?

>>> $user = User::find(5);
=> null

nullが返ってきます。このように存在しないidなどが来た場合には例外処理を行いますが、Laravelでは標準で例外を投げてくれるメソッドがあります。

>>> $user = User::findOrFail(5);
Illuminate\Database\Eloquent\ModelNotFoundException with message 'No query results for model [App\Models\User] 5'
>>> 

findOrFailを使えば例外を投げる処理を省くことができとても便利です。

次にすべてのユーザを取得してみましょう。

>>> User::all();
=> Illuminate\Database\Eloquent\Collection {#4286
    all: [
      App\Models\User {#4287
        id: 1,
        name: "tomo2cito",
        email: "test@test.com",
        email_verified_at: null,
        #password: "$2y$10$CoHE9v5oHTSMDmHvXQkE5evRzRPvrur6iu5Hy/Mg661PUCNc.i7Du",
        #remember_token: null,
        created_at: "2021-05-06 11:19:46",
        updated_at: "2021-05-06 11:27:36",
      },
      App\Models\User {#4288
        id: 2,
        name: "tanaka",
        email: "tanaka@test.com",
        email_verified_at: null,
        #password: "$2y$10$6gVHsREKsZ76DZlorxjxfeSqJ.9X9paoPEBZiVS8x63Q2LbCmQQwW",
        #remember_token: null,
        created_at: "2021-05-06 11:31:16",
        updated_at: "2021-05-06 11:31:16",
      },
    ],
  }
>>> 

allメソッドを使用するとすべてのユーザーのコレクションを返してくれます。コレクションは配列を操作するラッパーです。コレクションには様々なメソッドが準備されています。

pluck

例えばすべてのユーザーをの名前だけを取得したい場合は次のようにpluckメソッドを使用して実現できます。

まずユーザーの一覧をallを使い取得

>>> $users = User::all();
=> Illuminate\Database\Eloquent\Collection {#4290
    all: [
      App\Models\User {#4291
        id: 1,
        name: "tomo2cito",
        email: "test@test.com",
        email_verified_at: null,
        #password: "$2y$10$CoHE9v5oHTSMDmHvXQkE5evRzRPvrur6iu5Hy/Mg661PUCNc.i7Du",
        #remember_token: null,
        created_at: "2021-05-06 11:19:46",
        updated_at: "2021-05-06 11:27:36",
      },
      App\Models\User {#4292
        id: 2,
        name: "tanaka",
        email: "tanaka@test.com",
        email_verified_at: null,
        #password: "$2y$10$6gVHsREKsZ76DZlorxjxfeSqJ.9X9paoPEBZiVS8x63Q2LbCmQQwW",
        #remember_token: null,
        created_at: "2021-05-06 11:31:16",
        updated_at: "2021-05-06 11:31:16",
      },
    ],
  }

そのあとにpluckを使いnameだけを抽出。

>>> $users->pluck('name');
=> Illuminate\Support\Collection {#4286
    all: [
      "tomo2cito",
      "tanaka",
    ],
  }

first

コレクションの一番初めのデータを抽出したい場合はfirstメソッドを使います。

>>> $users->first();
=> App\Models\User {#4291
    id: 1,
    name: "tomo2cito",
    email: "test@test.com",
    email_verified_at: null,
    #password: "$2y$10$CoHE9v5oHTSMDmHvXQkE5evRzRPvrur6iu5Hy/Mg661PUCNc.i7Du",
    #remember_token: null,
    created_at: "2021-05-06 11:19:46",
    updated_at: "2021-05-06 11:27:36",
  }
>>> 

また配列のように扱うこともできます。

firstメソッドで取得したデータは以下のようにしても取得できます。

>>> $users[0];
=> App\Models\User {#4291
    id: 1,
    name: "tomo2cito",
    email: "test@test.com",
    email_verified_at: null,
    #password: "$2y$10$CoHE9v5oHTSMDmHvXQkE5evRzRPvrur6iu5Hy/Mg661PUCNc.i7Du",
    #remember_token: null,
    created_at: "2021-05-06 11:19:46",
    updated_at: "2021-05-06 11:27:36",
  }
>>> 

最後に

今回はLaravelのEloquentモデルとコレクションを学びました。Eloquentモデルはデータベースのデータを操作するために使用され、Laravelを勉強する上でとても重要なパートになります。またコレクションも使い方によってはコードを簡潔に記述していけます。いろいろな使い方をこのからの記事で紹介していけたらと思っています。それでは。

この記事が気に入ったらサポートをしてみませんか?