1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

laravelで入力値の引き継ぎ機能を作ろうとしたらつまづきまくったので全部メモ

Posted at

これがしたい

入力値の引き継ぎ
登録したあと消えないでほしい。登録後変更もできるようにしたい。

やったこと

1.クラスprofileのインスタンスを作成
2.テキストエリアとセレクトボックス入力値の引き継ぎ
3.インスタンス名->seve()の有り無し
4.複数チェックボタン
5.データーベースで扱う値は'code'ではなく'id'にしたほうがいい
6.初期値の空判定

1.クラスprofileのインスタンスを作成

profileコントローラーのupdate()で

$profile = Profile::where('user_id', $user['id'])->first();
if (empty($profile)) {
            $profile = new Profile();
        }

ユーザーIDを元に該当のレコードを取得する。
もしユーザーIDがなかったらインスタンス作成する。

※ここのif文を書いてなかったから更新したいのに、無限に登録され続けた。

2.テキストエリアとセレクトボックス入力値の引き継ぎ

profileコントローラーで定義

public function update(Request $request)
    {
      $inputs = $request->all();
      $profile->academic_background = $inputs['academic_background']; // 学歴(詳細)
    }

profileブレードで定義

<div class="form-group">
    <?php $inputName = 'academic_background'; ?>
    {!! Form::label($inputName, '学歴(詳細)', ['class' => 'col-form-label']) !!}
    <div class="col-sm-10">
    {!! Form::textarea($inputName, $profile->$inputName, ['rows' => '4','cols' => '1', 'class' => 'form-control']!!}
     </div>
 </div>

これでテキストエリアとセレクトボックスの入力値は引き継ぐことができた。

3.インスタンス名->seve()の有り無し

profileコントローラーのupdate()をする際に気をつけることがもう一つある。

$profile->save();

有りだと更新。無しだと登録。
気をつけよ。

4.複数チェックボックス

他のフォーム情報は1:1だったから、同じテーブルに渡せたが、複数チェックボックスだと1:多のテーブルを作らなければいけない。中間テーブルってやつ。その記事↓
https://qiita.com/kusano00/items/001bdc353136935bf4f4
(イメージ)
プロフィールID 1 

特技

  • 野球(ID1)
  • ラグビー(ID2)
  • サッカー(ID3)

↓こうなってればいい

プロフィールID 特技ID
1 1
1 3

作っていく

特技(skills)テーブル作る

    public function up()
    {
        Schema::create('skill_profiles', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('profile_id')->unssigned()->index('profile_id')->comment('プロフィールID');
            $table->integer('skill_id')->unsigned()->index('skill_id')->comment('特技ID');
            $table->timestamps();
        });
    }

profileモデルに追記

public function skills()
    {
        return $this->belongsToMany('App\Models\Skill', 'skill_profiles', 'profile_id', 'skill_id')->orderBy('sort')->withTimestamps();
    }

第1引数 値を取得したいクラス
第2引数 テーブル名
第3引数 外部キー
第4引数 関連キー

profileコントローラーのupdate()に追記

$profile->skills()->detach();
        $dates = $inputs['skill'];
        foreach ($dates as $date) {
            $default = Jobtype::where('code', $date)->first();
            $profile->skills()->attach($default['id']); // 特技
        }

detach()で前回のフォーム情報を削除
※detach()しないと前回情報も追加されるので注意
'code'を'id'に変換してprofileテーブルに格納。

更にinput()に追記

$skills = $profile->skills()->pluck('code')->toArray();
return view('user.profile.input')
   ->with('skills', $skills)

profileインスタンスの→skills()でID絞って→IDに該当する'code'取得->配列で
※デフォルト値セットする際にin_arrayでtrueにするため、配列。
viewに変数渡す。

profileブレードに追記

 <div class="form-group">
  <?php $inputName = 'skill'; ?>
  {!! Form::label($inputName, '特技', ['class' => 'col-form-label']) !!}
  <div class="col-sm-10">
    @foreach($selectSkills as $selectSkillCode => $selectSkillValue)
       <div class="form-check form-check-inline">
       {!! Form::checkbox($inputName.'[]', $selectBusinesstypeCode, in_array($selectSkillCode,$skills)  , [ 'id' => $inputName .$selectSkillCode, 'class' => 'form-check-input']) !!}
       {!! Form::label($inputName . $selectSkillCode, $selectSkillValue, ['class' => 'form-check-label']) !!}
       </div>
    @endforeach
  </div>
</div>

チェックボックスの引数
第1引数 フォーム名
第2引数 value
第3引数 デフォルト値
第4引数 属性

in_arrayの引数
第1引数 文字列
第2引数 整数の配列
(第3引数 true入れた方が良いが今回はうまく動作しなかったのでパス)

5.データーベースで扱う値は'code'ではなく'id'にしたほうがいい

理由:'code'は値を変更したい時があるが、'id'は変更しない。

前提:$profile->preferred_workplaceの値は'code'

変更方法:profileコントローラーのupdete()で

$inputs = $request->all();

フォームの入力値を取得して
profileインスタンスの'preferred_workplace'に格納。

$profile->preferred_workplace = $inputs['preferred_workplace']; // 希望勤務地

これだとフォーム入力値('code')がそのまま入ってしまうのでちょっと改良。

$date = $inputs['preferred_workplace'];
$default = Prefecture::where('code', $date)->first();
$profile->preferred_workplace = $default['id']; // 希望勤務地
$date フォーム入力値の 'code' 取得
$default Prefectureクラスのカラム名codeが$date(フォーム入力値)のレコードを一つだけ取得
$profile 取得したレコードのカラム名idをprofileテーブルに格納

データベースに渡す値を'id'に変換できたが、入力値の引き継ぎするときの値は'code'じゃないといけないからprofileコントローラーのinput()で'code'取得して->withしてあげる

public function input()
{
 $preferred_workplace=Prefecture::where('id',$profile['preferred_workplace'])->first();

return view('user.profile.input')
->with('preferred_workplace', $preferred_workplace)
}

6.初期値の空判定

profileコントローラーのinput()に追記

 if (empty($profile)) {
            $academic_background = null;
        }else{
            $academic_background = $profile->academic_background;
        }

 return view('user.profile.input')
      ->with('academic_background',$academic_background)

空のときはnullを入れて、そうじゃなかったらオブジェクト値を変数に入れる。->withでviewに渡す。

profileブレードを修正

{!! Form::textarea($inputName, $academic_background, ['class' => 'form-control' ]) !!}

デフォルト値で$profile->academic_backgroundのように、オブジェクトで取っていたがエラー出ちゃうので、変数に変更

複数チェックボックスの場合

コントローラー追記

 if (empty($profile)) {
            $preferred_job_types = array();
        } else {
            $preferred_job_types = $profile->preferred_job_types()->pluck('code')->toArray();
        }

return view('user.profile.input')
->with('preferred_job_types', $preferred_job_types)

ブレード修正

@foreach($selectJobtypes as $selectJobtypeCode => $selectJobtypeValue)
   {!! Form::checkbox($inputName.'[]', $selectJobtypeCode,in_array($selectJobtypeCode,$preferred_job_types), [ 'id' => $inputName . $selectJobtypeCode, 'class' => 'form-check-input']) !!}
   {!! Form::label($inputName . $selectJobtypeCode, $selectJobtypeValue, ['class' => 'form-check-label']) !!}
@endforeach
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?