ラボ > Laravel、Lumen:基本、DB関連

Laravel DB関連: モデル、マイグレーションなどなど

DBにテーブルを追加していきたい。そのメモ。「artisan」ってコマンドを使っていく

作成日:2022-12-02, 更新日:2023-01-06

基本

▼私の環境
WIN+Docker+Ubuntuでlaravelを使うための作業メモ

▼artisan関連
Laravel artisanのメモ

php artisan

sailを使っているので「./vendor/bin/sail」が必要

$ ./vendor/bin/sail php artisan xxx

→無しで実行するとエラーになるし、解決しようとあれこれやるとドツボにハマるので注意

関係のあるファイルたち

  • .env - 接続先などの情報
  • app/Models/xxx.php - model関連
  • database/xxx/xxx.php - マイグレーション、流し込みたいデータ(seeders)など
  • config/database.php - 基本、触らないけど、状況に応じて触るかも?
  • app/Providers/AppServiceProvider.php - 関係あるか微妙?

流れ

前提としてDBがすでに作成済み(すでにあるなら問題無し、無ければコンソール or phpMyAdminのようなGUIで作成)
これからテーブルを作成していくってとき

  1. 接続先などの情報(.envの編集)
  2. モデルファイルの作成(app/Models/xxx.php)
  3. マイグレーションファイルの作成(database/migrations/xxx.php)
  4. マイグレーションの実行
  5. 元データファイルの作成(database/seeders/xxx.php)
  6. seedersの実行

元からあるファイルたちの対応

Laravelをインストしたときにすでに作られているマイグレーションファイルたちは削除せずにそのままにしておく
→Laravelに慣れてから削除する…という方針

接続先などの情報(.envの編集)

「DB_〇〇〇」たちを自分の環境・接続情報に書き換える

モデルファイルの作成(app/Models/xxx.php)

$ ./vendor/bin/sail php artisan make:model Sample

「app/Models/LineResponseModel.php」に好きなメソッドを追加していく
→詳細は未調査。実際に使うときに調査の予定

モデルファイル作成時にマイグレーションファイルも一緒に作成する場合

$ ./vendor/bin/sail php artisan make:model Sample -m

Eloquent

クエリビルダ、ORM、Eloquent

▼Eloquentってのを使いたい場合

$ ./vendor/bin/sail php artisan make:model Sample -m

マイグレーションファイルも一緒に作成してくれる。作成してくれなくてもEloquentってのは使えるのかな?

Eloquent

Eloquentは「エロクアント」と読むらしい

クエリビルダとEloquent

クエリビルダとEloquentってのが両方ある

・クエリビルダの戻値: コレクション
・Eloquentの戻値: モデルオブジェクト
※Eloquentではクエリビルダの構文をそのまま使うことが可能

普通にSQLを投げたい…

使いこなしたら便利なんだろうけど、個人的に魅力を感じない

  • ファイル名の命名規則を初めとする条件があるらしい
  • 複雑なクエリを投げるためにはSQLを知っていないとダメらしい
  • クエリビルダやEloquentを使うために記載方法を調べる必要がある
  • バージョンが変われば設定や記載方法によってはエラーやバグになる

→学習コストを考えるとSQLを投げるのが一番良いような気がする

マイグレーションファイルの作成(database/migrations/xxx.php)

ファイルの作成

▼laravelの「ファイル: artisan」のあるとこにカレントを移して実行

$ ./vendor/bin/sail php artisan make:migration create_sample_table --create=sample

→「database/migrations/2022_12_01_224958_create_sample_table.php」が作られる

ファイルの修正

「database/migrations/2022_12_01_224958_create_sample_table.php」の「up()」の中身を作りたいようにする

$table->id();
$table->char('title', 128)->default('')->comment('件名');
$table->longText('temporary')->comment('仮データ');
$table->integer('disabled_at')->unsigned()->default(0);
$table->timestamps(); // created_at、updated_atを作成

※参考: Laravel 8.x マイグレーション / 利用可能なカラムタイプ

テーブルにコメントをつけたい

$table->comment('テーブルのコメント');

▼up()の中身のサンプル

public function up() {
  Schema::create('c_tests', function (Blueprint $table) {
    $table->comment('テーブルのコメント'');
    $table->char('title', 128)->default('')->comment('件名');
    $table->longText('temporary')->comment('仮データ');
    ~ 省略 ~
  });
}

マイグレーションの実行

$ ./vendor/bin/sail php artisan migrate

マイグレーションのロールバック

▼全部

$ ./vendor/bin/sail php artisan migrate:rollback

▼一つだけ

$ ./vendor/bin/sail php artisan migrate:rollback --step=1

元データファイルの作成(database/seeders/xxx.php)

$ ./vendor/bin/sail php artisan make:seeder SampleSeeder

「database/seeders/SampleSeeder.php」の「run()」の中身を作りたいようにする
→詳細は未調査。実際に使うときに調査の予定

seedersの実行

▼database/seedersの中のすべてを実行

$ ./vendor/bin/sail php artisan db:seed

▼database/seeders/SampleSeeder

$ ./vendor/bin/sail php artisan db:seed --class=SampleSeeder

SQLの実行

以前にまとめた古いメモだけど基本、同じはず → Laravel DB絡み

Eloquentだかクエリビルダを使うとラクらしいけど…最低限覚えておけばOKなヤツ

select文をマルっと実行
DB::select(select文);
select文を1件だけ実行
DB::selectOne(select文);
insert文をマルっと実行
DB::insert(insert文);
insertしたいデータを配列で渡して、保存後のデータを取得
DB::create(配列);

SQLをそのまま投げる

▼Facadesのほうを使う

~ 省略 ~
use Illuminate\Support\Facades\DB;
~ 省略 ~
    public static function 〇〇〇〇(〇〇〇, 〇〇〇) {
        ~ 省略 ~
        $q = 'select * from xxx where 1 and hoge=:hoge';
        $bind = array(
            'hoge' => 'xxx',
        );
        $record_many = DB::select($q, $bind);
        ~ 省略 ~
    }
~ 省略 ~

last_queryが欲しい

\DB::enableQueryLog();
$record_many = DB::select($q, $bind);
var_dump(\DB::getQueryLog());
// 必要かどうか…微妙
// \DB::disableQueryLog();
// \DB::flushQueryLog();

Eloquent + プライマリキーと日時が不要なとき

insertしたあとinsertしたレコードを取得したいとき色々とあるけど、希望するのは「保存したデータだけ」じゃなくレコードをマルっと取得したい
→PDOから「lastInsertId()」とかで取得してクエリを投げたいんだけど万が一、同時に複数の人からinsertがあったらタイムラグで変な値が返ってくるかもしれない…ってことでEloquentのほうからinsertする

▼insertしてから値を取得したいとき+エラー対策

$data_many = array( // カラムと値をセットした配列
    カラム1 => 〇〇〇,
    カラム2 => 〇〇〇,
    カラム3 => 〇〇〇,
);

$self = new 〇〇〇();
$self->timestamps = false; // タイムスタンプ(created_at, updated_at)を使うか?
$self->primaryKey = null; // プライマリキーを使うときは対象のカラム名(初期値: id)
$self->incrementing = false; // インクリメントを使うか
// $self->fillable = array(); // 書換えOKなカラム
$self->guarded = array(); // 書換えNGなカラム

// 保存データのセット
foreach ( $data_many as $row_colm => $row_val ) {
    $self[$row_colm] = $row_val;
}
$result = $self->save();

// 保存時に使ったデータとプライマリキー(id)が格納
// 上記の「timestamps」~「incrementing」は基本、すべてコメント。状況に応じて書き換える感じ
var_dump($self->original);

※基本はマルっとコメントで大丈夫だけど、諸々の事情で設定したいときは上記のような感じ