PHP
laravel
laravel5.4

[メモ]Eloquentの利用方法(1)

Laravel 公式ドキュメントに基づいて作成したものです。

モデル定義

全てのEloquentモデルは、Illuminate\Database\Eloquent\Modelを拡張する必要があります。

モデルの作成に使えるArtisanコマンド

モデルの作成:
php artisan make:model User

モデル作成時にデータベースマイグレーションも生成:

php artisan make:model TestModel -m

注;データーベースにテーブルを作成する:

$ php artisan migrate


Eloquentモデル規約

モデル名

Laravelで定められたモデルとテーブル名の対応関係例:
Flight(モデル)-----Flights(テーブル)

カスタムテーブル名を指定する(本文を参照)


主キー

Eloquentはテーブルの主キーがid、デフォルト状態で主キーがint、自動増分される整数
自動増分ではないを使う:モデルにpublicの$incrementingプロパティーを用意し、falseをセット

タイムスタンプ

created_at(作成時間)とupdated_at(更新時間)は自動更新
自動更新を利用しない:モデルの$timestampsプロパティーをfalseに設定
タイムスタンプのフォーマットをカスタマイズ:モデルの$dateFormatプロパティーを設定
タイムスタンプを保存するカラム名をカスタマイズする:モデルにCREATED_ATUPDATED_AT定数を設定

データベース接続

アプリケーションに設定されているデフォルトのデータベース接続を使用
異なった接続を使用したい:モデルに$connectionプロパティーを使用

モデルの取得

全レコードを取得

(取得されるのは$flightsモデルのCollectionインスタンスです)
$flights = App\Flight::all();


制約の追加

Eloquentモデルはクエリビルダとしても動作しますのでクエリに制約を付け加える
結果を取得するにはgetメソッドを使用
クエリビルダ

コレクション

allやgetで取得したIlluminate\Database\Eloquent\CollectionインスタンスのメソッドでEloquent結果を操作

コレクションについて詳しいドキュメント


結果の分割

数千のEloquentレコードを処理:chunkコマンド
//一番目の引数:いくつのレコードを処理するか
//二番目:クロージャ閉包関数
Flight::chunk(200, function ($flights) {
    foreach ($flights as $flight) {
        //
    }
});


データベース全体を繰り返し処理

cursorメソッドを使用
foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
    //
}


次に、コレクションの代わりに、これらのメソッドは1モデルインスタンスを取得して処理する方法を紹介:

モデル/集計の取得

主キー(id)で指定したモデル取得
$model=Model::find(id)


主キー(id)の配列で指定したモデル取得
$model=Model::find([1,2,3]);


クエリー条件にマッチした最初のレコード取得
$model=Model::where('colum',value)->first()


例外

モデルが見つからない時に、例外を投げる

$model=Model::findOrFail(id)
$model=Model::firstOrFail()

集計の取得

$count=Model::where('column',2)->count();
$max=Model::where('coulmn',1)->max

モデルの追加と更新

追加

$model=new Model;
$model->name=$request->name;
//saveメソッドが呼ばれると新しいレコードがデータベースに挿入されます。
//saveが呼び出された時にcreated_atとupdated_atタイムスタンプは自動的に設定されます
$model->save();

更新

$model=Model::find(1);
$model->name='xxxx';
$model->save();

複数モデル更新:複数モデル更新を行う時、実際にモデルが取得されるわけではない

App\Flight::where('active', 1)
          ->where('destination', 'San Diego')
          ->update(['delayed' => 1]);

複数代入

脆弱性を防ぐために、最初に複数代入したいモデルの属性を指定する必要がある。

モデルの$fillableプロパティで指定。(ホワイトリスト)
protected $fillable = ['name'];


新しいレコードをデータベースに挿入:createを利用
$flight = App\Flight::create(['name' => 'Flight 10']);


既に存在するモデルインスタンスへ属性を指定:fillを使う
$flight->fill(['name' => 'Flight 22']);


属性の保護

複数代入したくない属性の配列を指定:$guardedプロパティーを使用(ブラックリスト)
//priceだけは複数代入したくない
protected $guarded = ['price'];


全属性を複数代入可能:$guardedをクリアする
protected $guarded = [];


他の生成メソッド

firstOrCreate->
まず指定のレコードをデーターベースに見つけ、ない場合は新しいレコードを挿入
firstOrNew->
まず指定のレコードをデーターベースに見つけ、ない場合は新しいモデルインスタンスを生成するが、データーベースに保存されないので、saveを呼び出す必要があります。
updateOrCreate->
既存のモデルを更新するか、存在しない場合は新しいモデルを作成。

モデル削除

モデルによる削除:delete()
$flight = App\Flight::find(1);

$flight->delete();


キーによる既存モデルの削除:destroy(id)
App\Flight::destroy(1);

App\Flight::destroy([1, 2, 3]);

App\Flight::destroy(1, 2, 3);


クエリーによるモデル削除
$deletedRows = App\Flight::where('active', 0)->delete();


ソフトデリート

1.ソフトデリートを有効にする

モデルにIlluminate\Database\Eloquent\SoftDeletesトレイトを使い、deleted_atカラムを$datesプロパティに追加します。


2.データベーステーブルにdeleted_atカラムを追加する

スキーマビルダに作成するメソッドsoftDeletes()を使用。


3.モデルをソフトデリートする

モデルに対しdeleteメソッドを使用

4.削除の確認
trashedメソッドを使用。

ソフトデリート済みモデルのクエリ

ソフトデリートされたモデルは自動的にクエリの結果から除外されます。

1.ソフトデリート済みのモデルを含めるように強制したい場合:クエリにwithTrashed()メソッドを使う。
$flights = App\Flight::withTrashed()
                ->where('account_id', 1)
                ->get();


2.ソフトデリート済みモデルのみの取得:onlyTrashed()メソッドを使用
$flights = App\Flight::onlyTrashed()
                ->where('airline_id', 1)
                ->get();


3.ソフトデリートの解除:restore()

ソフトデリート済みのモデルを「未削除」に戻したい場合->モデルインスタンスに対しrestore()メソッドを使用
$flight->restore();


モデルの完全削除

forceDelete()を使う

// 1モデルを完全に削除する
$flight->forceDelete();

// 関係するモデルを全部完全に削除する
$flight->history()->forceDelete();