LaravelのModelの使い方まとめ!

Laravel

LaravelのModelの使い方について解説しています。 載せているコマンドやサンプルコードは、Laravelのバージョン9.0.2を使用して確認しています。

モデルを使用して、実際にEloquentでデータを取得したり、追加したりする方法については下記を参照してください。 [https://codelikes.com/laravel-eloquent-basic/]

LaravelのModel(モデル)について

LaravelのModelは、データベースとデータをやりとりするために作成します。 モデルを使うことで、LaravelのORMであるEloquentの機能を使って、データの取得や追加・更新などを行うことができます。

基本的には、テーブルとモデルは1対1になります。 Laravelに接続設定しているデータベースのひとつのテーブルにつき、ひとつのモデルを用意します。

LaravelのModelを作成する

LaravelのModelもartisanコマンドを使用することで作成できます。 下記のようにコマンドを実行することで、モデルを作成できます。

$ php artisan make:model Fruit

コマンドを実行すると、下記のようにモデルが作成されたことが確認できます。

$ php artisan make:model Fruit
Model created successfully.

実際に作成されたモデルを確認すると、下記のようにModelが作成されています。 デフォルトでは、app/Models配下にモデルが作成されるようになっています。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Fruit extends Model
{
    use HasFactory;
}

モデルと一緒にマイグレーションを作成する

データベースに新しいテーブルを作成するマイグレーションをモデルと一緒に作成することが可能です。 その場合にはモデルを作成するコマンドに-mオプションをつけて実行します。

$ php artisan make:model Fruit -m

実行すると、下記のようにモデルファイルと一緒にマイグレーションファイルも作成されます。

$ php artisan make:model Fruit -m         
Model created successfully.
Created Migration: 2022_05_04_081825_create_fruits_table

※-mは--migrationオプションの省略形です。--migrationを指定しても良いです。

LaravelのModelの命名規則

LaravelのModelの名前はテーブルに対して、単数形で書くように決まっています。

例えば、テーブル名がusersの場合はモデル名はUserになります。 先ほどのようにテーブル名がfruitsの場合はモデル名はFruitです。

複数の単語でテーブルを作成する場合は、アンダーバーで繋ぐスネークケースになります。 対応するモデルはキャメルケースで書きます。 例えば、テーブル名がuser_fruitsの場合はモデル名はUserFruitになります。

このように、テーブル名とモデル名を決められた規則で作成することで、Eloquentを使用して対象のテーブル操作が可能です。 先ほどのコマンドを使用して、モデルと一緒にマイグレーションファイルを作成するとテーブル名をつけてくれるので楽です。

モデルを別のテーブルに繋ぐには?

モデルを決められた名前のテーブル以外の別テーブルに繋ぎたい場合についてです。 その場合は、モデルクラスに下記のように$tableプロパティを作成することで、別テーブルに設定できます。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Test extends Model
{
    use HasFactory;

    protected $table = 'fruits';
}

上記はTestモデルなので、テーブルはtestsになります。 ですが、$tableを用意してfruitsを設定したので、fruitsテーブルに対して操作ができるようになります。

fillableとguardedについて

Laravelでデータを追加するためにcreateメソッドを使用しますが、使うためにはfillableかguardedの設定が必要です。 fillableにはデータ登録許可するカラムを指定します。 guardedにはデータ登録をさせないカラムを指定します。

fillableの設定

例えば、先ほど作成したFruitモデルにfillableを指定する場合は、下記のようにします。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Fruit extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'color', 'price'];
}

登録可能なカラムを全て指定します。 指定されたカラム以外には登録できません。

guardedの設定

guardedに指定する場合は、下記のようにします。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Fruit extends Model
{
    use HasFactory;

    protected $guarded = ['created_at', 'updated_at'];
}

入力させないカラムを指定します。 指定したカラム以外にはデータ登録できます。

fillableとguardedのどちらを使うか

基本的には作成したカラムの全部に対してデータを入れるかと思います。 guardedを使って、Laravelが自動的に入れてくれるタイムスタンプ(created_at・updated_at)だけ指定する方が楽なのかと思います。

入力するカラムが少ない場合などにfillableを使うようにすると良いのではないでしょうか。

データを取得するときにカラムを隠す

取得したデータのカラムを隠すには$hiddenを設定します。

例えば、Fruitモデルにデータを入れて、全てのデータをとって配列で出力してみます。 全てのデータを下記のように配列化して、ddで出力しました。

dd(Fruit::all()->toArray());

そうすると、このように出力されます。

^ array:3 [
  0 => array:6 [
    "id" => 1
    "name" => "apple"
    "color" => "orange"
    "price" => "100"
    "created_at" => "2022-05-04T10:11:59.000000Z"
    "updated_at" => "2022-05-04T10:11:59.000000Z"
  ]
  1 => array:6 [
    "id" => 2
    "name" => "banana"
    "color" => "yellow"
    "price" => "120"
    "created_at" => "2022-05-04T10:11:59.000000Z"
    "updated_at" => "2022-05-04T10:11:59.000000Z"
  ]
  2 => array:6 [
    "id" => 3
    "name" => "orange"
    "color" => "orange"
    "price" => "150"
    "created_at" => "2022-05-04T10:11:59.000000Z"
    "updated_at" => "2022-05-04T10:11:59.000000Z"
  ]
]

created_at・updated_at・priceを隠す場合は、下記のようにモデルに設定します。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Fruit extends Model
{
    use HasFactory;

    protected $hidden = ['price', 'created_at', 'updated_at'];
    protected $guarded = ['created_at', 'updated_at'];
}

$hiddenプロパティを用意して、表示しないカラムを指定しました。 こうすることで、先ほどと同じように出力すると、下記のようになります。

^ array:3 [
  0 => array:3 [
    "id" => 1
    "name" => "apple"
    "color" => "orange"
  ]
  1 => array:3 [
    "id" => 2
    "name" => "banana"
    "color" => "yellow"
  ]
  2 => array:3 [
    "id" => 3
    "name" => "orange"
    "color" => "orange"
  ]
]

指定したカラムのデータが返ってこないようになりました。 ちなみにcreateでデータを追加する場合は、hiddenに指定したカラムにもデータを入力することは可能です。

SQLをモデルに書くとスッキリ

モデルに任意のメソッドを作成して、Eloquentで発行するSQLをまとめておくことが可能です。 コントローラーに直接書くこともできますが、同じ内容を複数書く場合や長い場合は、コントローラーのソースコードが読みにくくなるのでモデルにまとめるとスッキリします。

例えば、先ほどのFruitモデルでcolorが赤色の物のみ抽出するクエリをモデルに書いてみます。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Fruit extends Model
{
    use HasFactory;

    protected $hidden = ['price', 'created_at', 'updated_at'];
    protected $guarded = ['created_at', 'updated_at'];

    public function fetchRedColorItems()
    {
        return $this::whereColor('red')->get();
    }
}

fetchRedColorItemsメソッドを作成しました。 モデル内では$thisで自分のことを指すことが可能です。$this::whereColorで、Colorカラムに’red’が指定されているものだけ取ってきて、呼び出し元に返しています。

呼び出す時には、対象のモデルをnewしてからメソッドを呼ぶようにします。

$fruitModel = new Fruit();
dd($fruitModel->fetchRedColorItems()->toArray());

上記のようにして、newしたモデルのインスタンスから作成したメソッドを呼ぶことが可能です。

コメント