Laravel checkboxで複数取得する方法 

3 min read読了の目安(約3200字

はじめに

inputのcheckboxを使って

1. 複数チェックの取得
2. チェックしたデータを保持する方法

をまとめてみました。

テーブル設計とリレーション

今回はusersテーブルcategoriesテーブル使っていきます。

userは複数のcategoryを持ち、categoryも複数のuserに紐づけられているので

多対多のリレーションになります。

テーブル設計

◎usersテーブル

migration
public function up()
   {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
        });
   }



◎categoriesテーブル

migration
public function up()
   {
        Schema::create('categories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
   }


◎category_userテーブル

migration
public function up()
   {
        Schema::create('category_user', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->integer('category_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->OnDelete('cascade');
            $table->foreign('category_id')->references('id')->on('categories')->OnDelete('cascade');
            $table->timestamps();
        });
   }



category_userテーブルで

migration
$table->foreign('user_id')->references('id')->on('users')->OnDelete('cascade');
$table->foreign('category_id')->references('id')->on('categories')->OnDelete('cascade');

でOnDelete('cascade')をつけておきましょう。 後々でdetachのときに一緒に削除するためです

リレーション設計

User.php
public function categories()
{
    return $this->belongsToMany(Category::class);
}

ここまで出来たら次はコントローラーの作成に入ります

コントローラー設計

Contorller
public function update(Request $request)
    {
        $user = Auth::user();

        $user->categories()->detach();
        $user->categories()->attach($request->category);


$user->categories()でリレーションをして、attach($request->category)でリクエストするカテゴリーを紐付けます。

テーブルでOnDelete('cascade')をつけたのは、detachで削除するときに、user_id, category_idを削除するためです。

次はBladeの設計です

Bladeの設計

ここが結構悩みました。 データの取得は出来たのですが、編集するときにデータの保持するのがなかなか詰まりました。

最初はoldを使ってデータ保持をやろうとしたのですがなかなかうまく行かず、oldを使わないでcheckedが含まれてるときでif文を作りました。

blade
@foreach ($categories as $category)
   @if($user->categories->contains('id', $category->id))
     <input type="checkbox" name="category[]" value="{{ $category->id}}" checked>
   @else
     <input type="checkbox" name="category[]" value="{{ $category->id}}">
   @endif 
    <label for="">
     {{ $category->name }}
    </label>
@endforeach

指定したidを判定するためにコレクションのcontains() メソッドを使って、指定したidが含まれているか確認しました。

ただ、oldを使ってデータ保持もやりたかったので、三項演算子を使って下記のようにも書いてみました。

blade
@foreach($categories as $category)
  <input type="checkbox" name="category[]" id=""  value="{{ $category->id }}" 
       {{ $category->id == old('category', $user->categories->contains('id', $category->id) ?? '') ? 'checked' : ''}}  >
    <label for="category">
       {{ $category->name  }}
     </label>  
@endforeach

保存して、また編集画面に遷移してもチェックボックスにcheckがついています!
色々なやり方がありますがご参考までに!!

参考

Laravel7.x コレクション contains

Laravel7.x リレーション