「速習Laravel 6」の感想・忘備録3

「速習Laravel 6」の感想・忘備録2の続き

モデル

マイグレーション

  1. php artisan make:migration create_items_table
    ※ itemsはテーブル名=複数形
    app/database/migationsにファイルが生成される。
  2. upメソッドの中のSchema::create内にカラム定義を追加する
    $table->string('name');
    メソッドはinteger, string, text, date, datetimeなど。
  3. php artisan migrateで実行
    upメソッドが実行される。
    php artisan migrate:rollbackでdownメソッドが実行される。
    (デフォルトではテーブル削除)

※ MySQL5.7.7未満だとエラーが発生する。
その場合、ユニークとなるカラムのサイズを$table->string('email', 191)->unique();のように191にする。
または、AppServiceProvider.phpのbootメソッドに Schema::defaultStringLength(191);を追加する。

シーダー

  1. php artisan make:seeder ItemsTableSeeder
    ※ Itemsはテーブル名=複数形
  2. rumメソッドにデータ登録処理を追加
    $now = new DateTime();
    DB::table('items')->insert(
      [ ['id' => 1, 'name' => 'hoge', 'created_at' => $now, 'updated_at' => $now],
      ['id' => 2, 'name' => 'hoge2', 'created_at' => $now, 'updated_at' => $now]
    ]);
  3. DatabaseSeeder.phpに作成したシーダーを登録
    runメソッド内に$this->call(ItemsTableSeeder::class);を追加。
  4. php artisan db:seedで実行
    個別のシーダーを指定する場合は--class=ItemsTableSeederを付ける。
    php artisan migrate:refresh --seedでデータベースの完全初期化(テーブル削除&作成&データ登録)

ファクトリ

  1. php artisan make:factory ItemFactory --model=Itemで生成
    Itemはモデル名=単数形
  2. database/factories/ItemFactory.phpのdefineメソッドを修正
    return [
      'name' => $faker->word, 'created_at' => now(),
      'updated_at' => now()
    ];
  3. シーダーで使う場合、database/seeds/ItemsTableSeeder.phpのrunメソッドを修正
    factory(App\Item::class, 10)->create(); // 10件生成される
    ※ config/app.phpのfaker_localeで言語設定を変更可能

データ取得用メソッド

全件取得:all()

Item::all();

主キーで取得:find()

Item::find(1);

絞り込み:where

  • Item::where('name', 'hoge')->get(); // 戻り値はCollection型
  • Item::where('id', '<', 5)->first(); // 戻り値はItem型
  • Item::where('name', ’LIKE', '%hoge%')->get();

他にもorWhere, whereIn, whereBetween, whereNull, whereYear, whereMonthなどのメソッドがある。

生の条件式:whereRaw()

Item::whereRaw('name = ? AND id < ?', ['hoge', 3])>get();

その他のメソッド

orderBy, offset, limit, groupByなど。
groupBy()を使う場合はselectRaw()で取得列を生の式で指定する。
selectRaw('name, COUNT(price) as price_count')

※ 集計値の取得だけであれば、avg, count, max,minメソッドを使う。
ただし、これらのメソッドは数値をそのまま返すので、get()やfirst()は不要となるので注意。

リレーション

booksテーブルにreviewsテーブルが複数紐づく場合

  1. Bookモデルにreviewsメソッドを追加
    public function reviews() {
      return $this->hasMany(Review::class);
    }
  2. Reviewモデルにbookメソッドを追加
    public function book() {
      return $this->belongsTo(Book::class);
    }
  3. viewに記述
    Bookインスタンス->reviews->bodyのように参照可能となる。

データの登録

  1. fillメソッドでリクエストデータを詰め込んでsaveメソッドで保存
    exceptメソッドで@csrfで生成されるワンタイムトークン_tokenを除く。
    ※ fill()を使わない場合は、$item->name = $request->input('name', 'default');のように手動でセットする。
    public function store(Request $request) {
      $item = new Item();
      $item->fill($request->except('_token'))->save();
      return redirect('create');
    }
  2. モデルに$fillableを定義
    protected $fillable = ['name'];
    ※fillメソッドでの割り当てを許可するカラムを配列で定義する。
    これによりマスアサインメント脆弱性が回避されている。

データの更新

  1. 編集フォームedit.blade.phpを作成
    <form method="post" action="/hello/{{ $item->id }}">
    @csrf
    @method('put')

    ※ formタグのメソッドはpostとし、@method(‘put’)でPUTメソッドを指定する
  2. コントローラにupdateメソッドを追加
    public function update(Item $item, Request $request) {
      $item->fill($request->except('_token'))->save();
      return redirect('hello/' . $item->id);
    }

    ※ ルーティングでRoute::put('hello/{item}', 'HelloController@update');のようにパラメータ部分をモデルの仮引数名と同じにすると、モデルインスタンスを取得することができる

バリデーション

バリデーションはコントローラ・モデル・フォームリクエストに定義することができる。

モデルに定義する場合

  1. モデルにstaticな配列変数でルールを定義
    public static $rules = [
      'name' => 'required|string|max:10'
    ];
  2. コントローラで実行
    $this->validate($request, Item::$rules);
  3. ビューでは$errorsでエラメッセージを取得可能
    @foreach($errors->all() as $error)
    <p>{{ $error }}</p>
    @endforeach
    ※ ViewErrorBag型なのでall()で配列にする

エラーメッセージの日本語化

https://gist.github.com/syokunin/b37725686b5baf09255b
などからダウンロードし、attributesに項目名を定義する。
'attributes' => [ 'name' => '商品名', ],
※ /resources/lang/ja/validation.phpに保存する。
※ /config/app.phpのlocaleをjaにする。(php artisan config:clearが必要)


0

【新しい記事】

【古い記事】

コメントを残す

メールアドレスが公開されることはありません。