0
0

More than 1 year has passed since last update.

[Laravel6] 簡易的な機能を作ってCRUDの全容を掴む

Posted at

作るもの

  • お問い合わせフォーム
  • REST(CRUD機能の作成)

作成の流れ

  • Model → Controller → Route → View

Read & Create

  • Model

    1. まずDBのテーブル及びカラム作成から行っていく

        - php artisan make:model Models/〇〇 (-mc) -mcとつけることで、マイグレーションとコントローラーファイルも用意してくれる

      • 実際のマイグレーションファイルの記述は以下のようになる
      public function up()
          {
              Schema::create('contact_forms', function (Blueprint $table) {
                  $table->bigIncrements('id');
                  //氏名、メールアドレス、url、性別、年齢、お問い合わせ内容
                  //unsigned -> 符号(+,-)がない
                  $table->string('your_name', 20);
                  $table->string('email', 255);
                  $table->longText('url')->nullable($value = true);
                  $table->boolean('gender')->unsigned();
                  $table->tinyInteger('age');
                  $table->string('contact', 200);
                  $table->timestamps();
              });
          }
      
    • php artisan migrate これを行うことで、マイグレーションファイルが起動し、実際にDBにテーブルが作成される。
    • Schema::create関数は、引数1に作成するテーブル名、引数2にカラムの作成手順を指定している
    • unsignedは、+,-の符号のうち、-を認めない機能。RDBで繋げるときに、この設定が違い違いになっていたらエラーが出るので、明示しておく。
  • Controller

    • RESTfulなコントローラーを作成する
    • php artisan make:controller 〇〇 —resource と入力することで、CRUD機能の土台を既に持っている、〇〇というControllerを作成することができる
  • View

    • リンク先にはRouteと同じ書き方が使える
    • laravelのformには@csrfが必須
    <form method="GET" action="{{ route('contact.create') }}">
    @csrf
                <button type="submit" class="btn btn-primary">
                  新規登録
                </button>
              </form>
    
  • Route

    • prefixは共通のフォルダ名、middlewareはAuth::routes();の認証機能を読み込んでる。
    Auth::routes();
    
    Route::group(['prefix' => 'contact', 'middleware' => 'auth'], function () {
        Route::get('index', 'ContactFormController@index')->name('contact.index');
        Route::get('create', 'ContactFormController@create')->name('contact.create');
    });
    

DBに投稿内容を保存

  • storeで書いていく

DBの投稿内容を表示

投稿の詳細

Route

Route::get('show/{id}', 'ContactFormController@show')
->name('contact.show');
  • 'show/{id}' と書くことで、各投稿に紐づけられたIDを参照し、その詳細な投稿内容を引っ張り出してくることが可能

Controller

public function show($id)
    {
        $contact = ContactForm::find($id);

if($contact->gender === 0){
            $gender = '男性';
        }

if ($contact->age === 1) {
            $age = '10代';
        }

        return view('contact.show', compact('contact','gender','age'));
    }
  • findは一つのデータを持ってくるイメージ
    • だから変数名も単数系
  • returnで渡しているデータ(compact)は、書き方の特徴として[$]が不要
    • それに複数の値を渡すことができる
  • DBでint他で管理しているものは、そのcontroller内で加工処理をしてあげる
    • 今回はintで管理しているものに、新しい変数を設定して、それをcompactでまとめてViewに送っている

View

{{ $contact->your_name}}
          {{ $gender}}
          {{ $age}}
  • Viewで表示するときは[$]が必要

別のViewから飛んでくる

<td><a href=
"{{route('contact.show', ['id' => $contact->id])}}">
詳細を見る</a>
  • ルートでパラメータを定義している場合は、route関数の第2引数としてパラメータを渡す。指定されたパラメータは自動的にURLの正しい場所へ埋め込まれる
    • 今回であれば、contact.showというrouteで定義した名前だけではなく、パラメータのidも定義してあげている
      • $contact→idはもちろんこのビューにもcontrollerからデータを飛ばしていることが前提にある

Edit画面

Route

Route::get('edit/{id}', 'ContactFormController@edit')->
name('contact.edit');
  • showで投稿の詳細画面を作成したが、イメージとしてはそれと同じ。
  • 各投稿の詳細を持ってくるためにパラメーターにidを指定して、その投稿を表示させる

Controller

public function edit($id)
    {
        //
        $contact = ContactForm::find($id);

        return view('contact.edit', compact('contact'));
    }
  • DBから投稿データを(idを基に)引っ張ってきて、Viewに投稿データを渡している

View

//createとほぼ同じ
//変更点は、各入力欄に初期値として投稿データを渡している
<input type="text" name="title" value="{{$contact->title}}">

//gender,ageのように数値で管理しているものの記述は少し違う

<input type="radio" name="gender" value="0"
 @if($contact->gender === 0 ) checked @endif >
男性
</input>

<input type="radio" name="gender" value="1" 
@if($contact->gender === 1 ) checked @endif>
女性
</input>
  • もちろんformで囲っているので、こっからDBに登録されているデータを更新する処理を書いていく必要がある
  • intで管理しているチェックボックス系は、引っ張ってきたデータがその数値と一致していたら、checked(selected)にする、というif文で対応する

Update

Route

Route::post('update/{id}', 'ContactFormController@update')
->name('contact.update');

Controller

public function update(Request $request, $id)
    {
        //
        $contact = ContactForm::find($id);

        $contact->your_name = $request->input('your_name');
        $contact->title = $request->input('title');
        $contact->email = $request->input('email');
        $contact->url = $request->input('url');
        $contact->gender = $request->input('gender');
        $contact->age = $request->input('age');
        $contact->contact = $request->input('contact');

        $contact->save();

        return redirect('contact/index');
    }
  • データの登録という面ではstoreと同じなので、型はstoreを流用
  • storeと違う部分
    • 現在のデータを持ってくる(新しくインスタンスを作成することはしない)

View

Editです
<form method="POST" 
action="{{route('contact.update', ['id' => $contact->id])}}">
  • action先にcontrollerのupdateメソッドを指定している
  • 各投稿の情報を基にデータの更新作業をしているので、idの指定は忘れない

Destroy

Route

Route::post('destroy/{id}', 'ContactFormController@destroy')
->name('contact.destroy');
  • その投稿を削除するので、show,editと同じ

Controller

public function destroy($id)
    {
        $contact = ContactForm::find($id);
        $contact->delete();

        return redirect('contact/index');
    }
  • データを一つ引っ張ってきて、deleteするだけ

View

<form method="POST" action="{{route('contact.destroy', ['id' => $contact->id])}}" id="delete_{{$contact->id}}">
          @csrf
          <a href="#" class="btn btn-danger" data-id="{{$contact->id}}" onclick="deletePost(this);" type="submit">削除する</a>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
<script>
function deletePost(e){
  'use strict';
  if (confirm('本当に削除していいですか?')){
    document.getElementById('delete_' + e.dataset.id).submit();
  }
}
</script>
@endsection
  • show.bladeのなかにformを二つ作っている
  • ごちゃごちゃしているのは、削除ボタンを押したときに「本当に削除しますか?」という表示を挟んでいるから
0
0
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
0
0