見出し画像

laravelにおける投稿機能・一覧表示の実装方法

私は、今回PHP言語、フレームワークにlareavelを使いエビングハウスの忘却曲線を元に学習を効率的に行うことができるアプリを作成していきます。

1.目的

投稿できるようにしていきます。

2.使うもの

なし

3.方法

①terminalにて以下のコマンドを実行し、マイグレーションファイルを作成します。

% php artisan make:migration create_items_table --create=items

create_items_table  :ファイル名
items  :テーブル名

②database/migrations/以下に作成されたファイルを以下のように編集します。

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateItemsTable extends Migration
{
   /**
    * Run the migrations.
    *
    * @return void
    */
   public function up()
   {
       Schema::create('items', function (Blueprint $table) {
           $table->id();
           $table->string('name');
           $table->string('url');
           $table->text('text');
           $table->timestamps();
       });
   }
   /**
    * Reverse the migrations.
    *
    * @return void
    */
   public function down()
   {
       Schema::dropIfExists('items');
   }
}

$table->カラム型('カラム名');というようにしカラムを定義します。

③terminalにて以下コマンドを実行してテーブルを作成します。

%php artisan migrate

④ ​Itemモデルを以下のコマンドを実行して作成をします。 

%php artisan make:model Item

モデル名は、単数系で記述を行います。その決まりによって作成することで、テーブルとモデルの関連付けが行われます。

⑤バリデーションをItemsControllerに追加していきます。
storeメソッドに以下の内容を追記していきます。

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Book;
use Validator;

class ItemsController extends Controller
{
   /**
    * Display a listing of the resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function index()
   {
       $items = Item::where('user_id',Auth::user()->id)
   }
   /**
    * Show the form for creating a new resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function create()
   {
       //
   }
   /**
    * Store a newly created resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @return \Illuminate\Http\Response
    */
    //
   public function store(Request $request)
   {
           //以下追記
       $validator = Validator::make($request->all(),[
           'name' => 'required',
           'url' => 'required',
           'text' => 'required',
       ]);
       if($validator->fails()){
           return redirect('/item/create')
               ->withInput()
               ->withErrors($validator);
       }
       //ここまで
   }
   /**
    * Display the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   
}

 Illuminate\Http\Requestオブジェクトにより提供されているvalidateメソッドによりを使用しています。
バリデーションルールにパスすると、コードは正常に実行され続けます。

またバリデーションには以下のようなルールが存在します。

画像1

バリデーションで失敗した場合
withInput()メソッドにより入力値をセッションへフラッシュデータとして残します。これによりredirectした先で再表示できるようになります。
redirect()メソッドにより引数で指定したパスへリダイレクトすることができます。
withErrors($validator)メソッドを使うことでバリデーションのエラー内容をフラッシュデータとしてセッションに保存しどのテンプレートであっても$errors変数としてアクセスすることができます。

⑥次に登録処理をItemsControllerに作成していきます。
ItemsControllerに以下の内容を追記していきます。

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Item;
use Validator;

class ItemsController extends Controller
{
   /**
    * Display a listing of the resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function index()
   {
       $items = Item::where('user_id',Auth::user()->id);
   }
   /**
    * Show the form for creating a new resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function create()
   {
       return view('items.create');
   }
   /**
    * Store a newly created resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @return \Illuminate\Http\Response
    */
   public function store(Request $request)
   {
       $validator = Validator::make($request->all(),[
           'name' => 'required',
           'url' => 'required',
           'text' => 'required',
       ]);
       if($validator->fails()){
           return redirect('item/create')
               ->withInput()
               ->withErrors($validator);
       }
       //以下追記
       $items = new Item;
       $items->name = $request->name;
       $items->url = $request->url;
       $items->text = $request->text;
       $items->save();
       return redirect('/');
       //ここまで
   }
   /**
    * Display the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   
}

登録するには、Eloquentモデル「Item」に対し、値を代入した後にsave()メソッドで保存します。処理が終わったらreturn redirect('/')でルートに遷移します。

⑦app/resources以下にcommonディレクトリを作成しその中にerrors.blade.phpファイルを作成します。
そしてerrors.blade.phpファイルを以下のように編集します。

@if (count($errors)>0)
 <div class="alert alert-danger">
   <div><strong>入力した文字を修正してください</strong></div>
   <div>
     <ul>
       @foreach($errors->all() as $error )
         <li>{{ $error }}</li>
       @endforeach
     </ul>
   </div>      
 </div>
@endif  

バリデーションのエラーがあった場合にこのテンプレートを読み込んでおくだけで入力チェックのエラー表示ができます。

ここに書かれてある$errors変数は、laravelfフレームワークのバリデーション処理で問題がある際に自動生成されます。そのため、入力チェックでエラーがあれば$errors変数が生成され、エラー内容が$errors変数に配列で格納されます。

⑧app/resources/items以下にcreate.blade.phpファイルを作成します。
そしてcreate.blade.phpファイルを以下のように編集します。

@extends('layouts.app')
@section('content')
 <div class="card-body">
   
   
   @include('common.errors')
   <form  enctype="multipart/form-data" action="{{ url('item') }}" method="POST"
   class="form-horizontal">
     @csrf
     <div class="form-group">
       <div class="card-title">
         題目
       </div>
       <div class="col-sm-6">
         <input type="text" name="name" value="{{ old('name') }}" class="form-control">
       </div>
       <div class="card-title">
         URL
       </div>
       <div class="col-sm-6">
         <input type="integer" name="url" value="{{ old('url') }}" class="form-control">
       </div>
       <div class="card-title">
         text
       </div>
       <div class="col-sm-6">
         <input type="text" name="text" value="{{ old('text') }}" class="form-control">
       </div>
     <div class="form-group">
       <div class="col-sm-offset-3 col-list">
         <button type="submit" class="btn btn-primary">
           Save
         </button>
       </div>
     </div>
     
   </form>
 </div>
 

@endsection

@extends('layouts.app')でベース・テンプレートを読み込んでいます。
また、layouts.appはlayouts/appと同意です。

@section('content')から@endsectionの間に文字列/HTML/スクリプトなどを入れます。
ベーステンプレートの@yield('content')の箇所に@section('content')を挿入します。

@csrfは、CSRF(Cross-Site Request Forgeries)からの保護をしています。
CSRFというのは、ユーザーになりすまして不正行為を行うハッキングの手法です。laravelには、CSRFから簡単にアプリケーションを守るためのヘルパー関数が用意されています。

@include('common.errors')は、common/errors.blade.phpを読み込みます。
フォームのバリデーションエラーを表示したいテンプレートに記述するだけで簡単にできます。

⑨最後に投稿したものを表示できるようにしていきます。
ItemsControllerに以下の内容を追記していきます。

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Item;
use Validator;

class ItemsController extends Controller
{
   /**
    * Display a listing of the resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function index()
   {
           //以下追記
       $items = Item::orderBy('created_at','desc')->get();
       return view('items.index',compact('items'));
       //ここまで
   }
   /**
    * Show the form for creating a new resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function create()
   {
       return view('items.create');
   }
   /**
    * Store a newly created resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @return \Illuminate\Http\Response
    */
   public function store(Request $request)
   {
       $validator = Validator::make($request->all(),[
           'name' => 'required',
           'url' => 'required',
           'text' => 'required',
       ]);
       if($validator->fails()){
           return redirect('item/create')
               ->withInput()
               ->withErrors($validator);
       }
       $items = new Item;
       $items->name = $request->name;
       $items->url = $request->url;
       $items->text = $request->text;
       $items->save();
       return redirect('/');
   }
   /**
    * Display the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   
}

変数itemを定義しその中に、登録されたItemを降順で代入しています。
view()関数は第二引数にビューで使用するデータを配列で受け付けます。
配列のキーは、ビューの中で変数になります。

⑩app/resources/items/index.blade.phpに以下の内容を追記します。

@extends('layouts.app')
@section('content')
<h1>hello World</h1>
<a href="{{ url('item/create') }}" >投稿</a>
//以下追記
<h2>投稿されたもの</h2>
@foreach($items as $item)
<div>{{ $item->name }}</div>
<div>{{ $item->url }}</div>
<div>{{ $item->text }}</div>
@endforeach
//ここまで
@endsection

@foreachディレクティブでは$items変数内のデータレコード数だけ処理を繰り返します。

4.まとめ

以上で投稿機能、一覧表示機能の実装は完成です。
次のように投稿できたらおっけい!です。
ありがとうございました!!!

画像2


この記事が気に入ったらサポートをしてみませんか?