top of page
  • 執筆者の写真英伸 後

Laravel演習 03.Laravel モデルの作成

更新日:2021年7月14日

モデルについて


Modelはアプリケーション(プロジェクト)のデータベース連携機能を集中的に集めたLaravelの要素です。


Modelを構成するのはマイグレーションというデータベースの構成管理ファイルと

モデルというLaravelで準備されているModelクラスを継承して個別にデータベースを操作する機能を集約させたファイルです。

いずれもPHPで記述され、クラスとしてアプリケーション(プロジェクト)のなかで管理されます。


アプリケーション(プロジェクト)の全体設定


まず、Model関連のファイルを生成する前にLaravelとデータベースとの連携を行う全体設定を行います。

アプリケーション(プロジェクト)自体の全体設定はプロジェクトルートディレクトリ(ここではhttpd>DMENAフォルダ)直下の.envファイルで行います。

ここでデータベース関連以外の全体設定もしてしまいます。


まず.env をひらきます。


デフォルトではAPP_NAME=laravel になっているので、これをDMENAに変更します。


次にデータベース関連の全体設定をします。

データベースのプロファイルを確認するためにXampp Controll PanelでMySQLを立ち上げて、表示される各プロファイルを確認します。


まず重要なのがPort(s) です。大体XamppでMySQLを動かすと3306番が付与されるようです。.env でもデフォルトで3306番が記載されています。

そしてデータベース名。

これはこのアプリ用に作成したMySQL用のデータベース名を記載します。

データベースはControll Panelの「Admin」ボタンを押すと立ち上がるPHP MyAdminという管理ツールから作成できます。

この画面ではこのアプリケーションようにdmenaというデータベースがすでに作成されています。


以上を確認して.envに戻ります。そして確認した情報をデータベースプロファイルに反映させます。


DB_PORT=3306

DB_NAME=dmena

DB_USERNAME=root

DB_PASSWORD= ※Xamppではデフォルトブランクになっていますから.envもブランクで大丈夫です。

しかし基本は何らかの設定をすべき箇所です。


次に文字コードの設定を行います。

これは.envではなくプロジェクトルートディレクトリ以下 APP>Providers>AppServiceProviders.php ファイルを修正します。


まず、上部のクラス導入部に


use Illuminate\Support\Facades\Schema;  -※\はバックスラッシュ


を追記して


boot() メソッドの中に


Schema::defaultStringLength(191);


を追記します。


AppServiceProviders.phpを保存します。


最後にタイムゾーンの設定を行います。

タイムゾーンはプロジェクトルートディレクトリ以下 config>app.php ファイルを修正します。


このtimezone とlocale を修正します。


'timezone'=>'Asia/Tokyo',

'locale'=>'ja',


.envを保存します。


マイグレーションの作成


マイグレーションは冒頭に触れたようにデータベースの構造管理を行います。

例えばデータベースシステムにはMysql、SQLiteやpgsqlなど様々な種類があります。

またそれぞれが常時バージョンアップを進行させています。

このことにより、せっかく作成したデータベースが例えばMySQLのバージョンアップにより構造から作り直さなくてはならない、となると非常に煩雑な作業を行わなくてはなりません。

マイグレーションによりデータベースの構造、つまりテーブルやカラムの形を定義して、土台のエータベースシステムに変更があった場合でも簡単に作成したデータベースが再現できます。

その意味では構造管理でもありバージョン管理機能も兼ね備えている、と言っていいでしょう。


マイグレーションファイルはプロジェクトルートディレクトリ以下 database>migration ディレクトリに生成されます。

生成はコマンドプロンプト、あるいはPower Shell からLaravelのartisan コマンドを打って行います。


php artisan make:migration create_corporations_table


corporationsが作りたいテーブル名です。複数形になっている点留意しておいてください。

create_corporations_table はcorporationsというtableをcreateしなさい、という指示文です。


コマンドをEnterします。

Created Migration: 2021_07_07_135620_create_corporations_table


このようなメッセージが表示されたらマイグレーションファイルの生成が完了です。

ディレクトリ database>migrations ディレクトリの中に「2021_07_07_135620_create_corporations_table.php」というファイルが出来上がっています。

これがマイグレーションファイルです。

ファイル名は自動的に生成されます。前半はファイルを生成した年月日時刻、そのあとにコマンドで打った指示文が続きます。


ここにマイグレーションファイルを作成して必要項目を書き込み、php artisan migrate とコマンドを叩けばSQLのCreate Table corporations{} のと同じ仕事をマイグレーションがしてくれるわけです。

実演の前に、migrationsディレクトリ内の他のファイルを削除してください。

使うことはないので削除で構いませんがVisual Studio Code なら削除の際にRecycle Bin に退避させてくれるのであとで復活可能です。


そのうえで「2021_07_07_135620_create_corporations_table.php」を開きます。


マイグレーションファイルを作成すると基本構文はすでに記述されています。

大きな説明をすると、

①まずこのファイルは

 ・Migration

 ・Blueprint

 ・Schema

 の3つのクラスを引用して作成されています。

②そしてCreateCorporationsTableというクラスをMigrationを継承してここに作られます。

③そしてCreateCorporationsTableはMigrationにあるup() とdown() の2つのメソッドから構成されて います。

up()はcreateやaddの実行、down()は削除を行うメソッドです。


up()の中で、テーブルの作成はSchemaクラスのcreateメソッド、フィールド(カラム)の設定はBlueprintクラスのメソッドで行い、その結果を$table という変数にしてcreateメソッドの第二引数に渡しています。

このなかにすでに

$table->id();

$table->timestamps();

の2行が記述されていますが、前者はレコードの通し番号、後者はレコード作成時のタイムスタンプで、テーブル作成時に設置が推奨されています。


down()の中にはSchemaからのdropメソッドがすでに記述されています。dropあとのIfExists は引数のテーブルがあったなら、という意味です。


Blueprintのメソッドでフィールドの定義を行ってゆきたいと思います。

基本的には

$table->increment(id);

という形ですincrementのところにデータ型、()内にフィールド名を定義してゆきます。

大体長さ(Length)は第二引数で指定できるようなので、それぞれ定義します。

一意(Unique)であるフィールドについては追加で->unique()を加えます。

NULLがOKなフィールドも->nullable()の追加で属性化します。

プライマリキーの設定も->primary()で'Corp_id_f'に追加定義します。


$table->id('id');

$table->char('Corp_id_f',25)->unique()->primary();

$table->char('Corp_nm_f',75);

$table->char('Corp_addr_f',150)->nullable();

$table->char('Corp_tel_f',40)->unique();

$table->char('Corp_dept_f',40)->nullable();

$table->char('Corp_mail_f',75)->unique();

$table->char('Corp_pw_f',15);

$table->char('Corp_adpw_f',20);

$table->timestamp('Corp_reg_f');


さらにup()のメソッドの中、Schema::createをif文で囲みます。


if(!schema::hasTable('corporations')){


Schema::create(・・・・・);


}

データベースが'corporations'というテーブルを持って(hasTable)いなければ(!)、'corporations'を作れ、という指示です。


Blueprintのメソッド、特にカラム定義(columnDefinition)についてはこちらのリファレンスに詳細が掲載されています。

https://laravel.com/api/8.x/Illuminate/Database/Schema/Blueprint.html



こうしてマイグレーションファイルの準備ができたら、このファイルを実行します。


artisanコマンドで


php artisan migrate


を叩きます。


ここでVisual Code Studio のTerminal機能でartisanコマンドを打ってみます。

Visual Code Studioの最上部メニューバーにあるTerminal→New Terminal でPowerShellが起動します。

最初からディレクトリがDMENAになっていますのでCMDを呼び出すのに比べ格段に作業がはかどります。


ステータスがMigrating→Migrateに変化してマイグレーションファイルの実行が完了します。


ここで、目論見通り「dmena」データベースに「corporations」テーブルができているか確認します。

Xampp Control PanelからPHP MyAdminを起動させます。


dmena 配下にcorporationsテーブルが生成されています。


定義したフィールド群も目論見通り生成されています。

Migrationを利用して、このようにしてテーブルやフィールドといったデータベースの構成管理を行います。


モデルの作成


先回の投稿で説明した通り、Laravel はMVCモデルに基づいて構成されており、MVCのMはModelであり、Modelはデータベースの操作やデータのオブジェクト化に関して責任を持っています。

LaravelにはEloquent ORM(Object Relational Mapping)という機能が実装されています。ORMとは2つのシステム間で本来互換性のないデータを行き来させるための翻訳機能です。

Eloquent ORMはLaravelで動くPHP(ControllerやView)とMySQLなどのDB間の仲介を行います。

Eloquent ORMには様々な機能が実装されており、特にMVCの中でAPI的な機能を果たすプロパティやメソッドを集めたModelというクラスがあります。

(マイグレーションもEloquantが持つクラスの一つです)

開発者はこのModelクラスを継承したクラスファイルを作成し、そのアプリケーション個別のカスタマイズをしてMVCモデルにおけるデータベース制御の橋頭保にします。


アプリケーション用のModelクラスはアプリケーションのデータベーステーブルと関連付けられている必要があります。

そのためにネーミングルールがあります。

先に触れたようにここでは「corporations」というテーブルをマイグレーションを使って作成しています。

このテーブルに関連付けるModelクラスの名称は「Corporation」とします。


・テーブル名の先頭文字を大文字にする

・テーブル名を複数形にして、Modelクラス名では単数形にする

Ex.テーブル名:Companies クラス名:Company


Modelクラスはartisanコマンドで生成します。


php artisan make:model Corporation



Model created successfully. というメッセージが表示されたらモデルの生成が完了します。



app>Models デイレクトリに「Corporation.php」が生成されていることが確認できます。(以下Corporationモデルと呼ぶ)

Corporationモデルの中にはデフォルトでいくつかの記述がなされています。


use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;


はそれぞれ、EloquentのHasFactoryクラス、Modelクラスを継承する旨の宣言です。


次のclass Corporation extends Model{} の中にDMENA特有のプロファイルや機能を記述してゆきます。


use HasFactory;


の下最初に記述すべきなのが、


protected $table = 'corporations';


です。

実は先に触れたようにクラス名と対応テーブル名の間のネーミングルールに則っていればこの行は不要です。

が、存在しても実害はないので備忘録的に記述しておきます。


次にテーブルにおけるプライマリーキーの指定です。

マイグレーションを生成する際にデフォルトで


$table->id();


というプロファイル指定がありました。

これはこのまま残すと'id'というオートインクリメンタルなフィールドができ、それがプライマリーキーになります。

しかし、今回は'id'とは別に'Corp_id_f'というフィールドを設け、それをプライマリーキーにしました。


$table->id('id');

$table->char('Corp_id_f',25)->unique()->primary();


これでLaravel上で'Corp_id_f'がプライマリキーになったかというと十分ではなく、Corporationモデルでもそれを定義する必要があるのです。

Corporationモデルに

protected $primaryKey = 'Corp_id_f';


と定義します。


次に書くフィールドに対してfillableとguarded を指定します。

fillable というのはLaravelがInsertやUpdateなどの操作ができるフィールド指定です。ホワイトリストを指定するようなものです。

逆にguarded はLaravelからの操作を禁止したいフィールドです。こちらはブラックリスト的にあものになります。

今回、corporations テーブルのほとんどのフィールドはユーザーからの入力情報で満たされ(fill)るので'id'と'Corp_reg_f'以外はfillableにしておきます。

'Corp_id_f','Corp_pw_f','Corp_adpw_f'はサーバー側で生成する予定なので、これらもfillableにするのは悩ましいところですが、今後の学習の中で必要に応じて修正します。


protected $fillable = [

'Corp_id_f',

'Corp_nm_f',

'Corp_addr_f',

'Corp_tel_f',

'Corp_dept_f',

'Corp_mail_f',

'Corp_pw_f',

'Corp_adpw_f'

];


これを保存してCorporationモデルを確定させるとMVCのM側の準備は完了です。


ちなみにLaravelでデータベースを動かす場合、DBクラスを使ってControllerのメソッドに直接クエリを書く、というやり方も可能です。

しかし、この場合受け渡しされるデータは連想配列という形でオブジェクト化されます。

連想配列を理解して、PHPで紐解けばデータはLaravel側(ControllerやView)でもいろいろな形で利用できるのですが、オブジェクト自体をLaravel側でネイティブに扱うことはできません。

その点、Eloquent Modelに基づくオブジェクトはLaravel側でネイティブに扱うことができ、設計の自由度が格段に上がります。


次回はMVC+RのR、ルーティングについて解説をしてゆきます。


閲覧数:51回0件のコメント

最新記事

すべて表示
bottom of page