การสร้าง CRUD เบื้องต้น สำหรับ Laravel 5.6


Credit: https://itsolutionstuff.com/post/laravel-56-crud-application-for-starterexample.html

หน้าจอที่จะทำออกมา Layout Screenshot

Index Page
Show Page
Edit Page
Step 1 : Install Laravel 5.6

ดูวิธีติดตั้งที่ https://vzrnote.blogspot.com/2016/04/install-laravel-5-with-xampp-on-windows.html ซึ่งในโพสท์นั้นเป็นการติดตั้งด้วย xampp เพื่อให้จัดการฐานข้อมูลได้ง่าย แต่ในโพสท์นี้จะรัน built-in server ที่มากับ Laravel ซึ่งจะใช้ Port 8000 ก็เลยจะไม่ชนกับ Apache Port 80 ที่เราใช้บน Xampp ปกติ

วิธีการติดตั้งคร่าวๆ 

1. ติดตั้ง Xampp ตั้งค่าผู้ใช้ฐานข้อมูลให้เรียบร้อย

2. เปิด cmd ติดตั้ง Composer อย่าลืมตั้งค่า PATH ของ composer ใน Environment system variables ของ composer ให้เรียบร้อย Path ดังนี้
C:\Users\YOUR_USERNAME\AppData\Roaming\Composer\vendor\bin
3. ติดตั้ง Laravel ด้วยคำสั่ง
composer global require "laravel/installer"
4.  ใน cmd เข้าไปยังพาธโฟลเดอร์ที่จะสร้างโปรเจ็ค ซึ่งใน xampp ก็คือ C:\xampp\htdocs แล้วรันคำสั่งสร้างโปรเจ็คใหม่ ในที่นี้โปรเจ็คชื่อ blog สามารถใช้ได้ 2 คำสั่ง อันไหนก็ได้ อันแรกใช้ laravel สร้าง
laravel new blog 
หรือใช้ composer ช่วยสร้างก็ได้
 composer create-project --prefer-dist laravel/laravel blog
รอสักพักจนเสร็จ ดูใน htdocs ก็จะพบว่ามีโฟลเดอร์ blog พร้อมไฟล์เริ่มต้นข้างในเรียบร้อย

Step 2: Database Configuration

ในที่นี้เราได้เข้าไปสร้าง database เปล่าๆ ชื่ิอ blog ใน phpmyadmin (จากที่ติดตั้ง xampp ก็ start mysql ใน xampp ด้วย) เตรียมไว้

จากนั้นก็เข้าไปดูในโฟลเดอร์ blog เปิดไฟล์ .env ขึ้นมา เพื่อแก้ไขการตั้งค่าการเชื่อมต่อฐานข้อมูล ในที่นี้ก็ตั้งค่าแบบนี้
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=blog
DB_USERNAME=root
DB_PASSWORD=1234
แก้ไข charset ให้เป็น utf8 โดยเข้าไปที่โฟลเดอร์ config เปิดไฟล์ database.php ขึ้นมา แก้ตรง charset และ collation ของ mysql
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

Step 3: Create products Table and Model

เวลาเราสร้างฐานข้อมูลใน Laravel เราจะสร้างในลักษณะ migration คือการรันไฟล์ที่เพื่อสร้างฐานข้อมูลตามที่เราเขียนกำหนดผ่าน cmd นั่นแหละ

อ่านรายละเอียดเพิ่มเติม Laravel 5: มาใช้ Migration, Models, Factory and Seeding กันเถอะ

ดังนั้น เราจะสร้าง migration สำหรับตารางชื่อ "products" ผ่าน php artisan โดยรันคำสั่งใน cmd ดังนี้ (ตอนนี้ cmd อยู่ที่พาธ C:\xampp\htdocs\blog)
php artisan make:migration create_products_table --create=products
พอรันเสร็จ เมื่อเราเข้าไปดูที่โฟลเดอร์  blog ใน database/migrations ก็จะพบว่ามีไฟล์ที่ถูกสร้างขึ้นใหม่ เช่น ชื่อ 2018_05_11_124801_create_products_table.php

ใส่ฟีลด์ที่ต้องการเพิ่มเข้าไป เช่น name, detail

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->text('detail');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}


Step 4: Add Resource Route

เพิ่ม route ให้รู้จัก product controller (เดี๋ยวกำลังจะสร้าง) โดยเปิดไฟล์ routes/web.php แล้วเพิ่มโค้ดต่อไปนี้ ต่อจากอันล่าสุด

Route::resource('products','ProductController');


Step 5: Create ProductController

สร้าง controller สำหรับ products โดยรันคำสั่งใน cmd
php artisan make:controller ProductController --resource --model=Product

จะพบว่าในโฟลเดอร์มีไฟล์ที่ถูกสร้างขึ้นมาคือ app/Http/Controllers/ProductController.php และ app/Product.php ซึ่งใน ProductController จะประกอบไปด้วย 7 methods ด้วยกัน ได้แก่
  1. index()
  2. create()
  3. store()
  4. show()
  5. edit()
  6. update()
  7. destroy() 
ก็เสริมรายละเอียดในแต่ละเมธอด ก็อปโค้ดต่อไปทั้งหมดนี้ลงในไฟล์ app/Http/Controllers/ProductController.php

<?php
namespace App\Http\Controllers;

use App\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $products = Product::latest()->paginate(5);
        return view('products.index',compact('products'))
            ->with('i', (request()->input('page', 1) - 1) * 5);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('products.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        request()->validate([
            'name' => 'required',
            'detail' => 'required',
        ]);


        Product::create($request->all());
        return redirect()->route('products.index')
                        ->with('success','Product created successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function show(Product $product)
    {
        return view('products.show',compact('product'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function edit(Product $product)
    {
        return view('products.edit',compact('product'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Product $product)
    {
        request()->validate([
            'name' => 'required',
            'detail' => 'required',
        ]);
        $product->update($request->all());
        return redirect()->route('products.index')
                        ->with('success','Product updated successfully');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function destroy(Product $product)
    {
        $product->delete();
        return redirect()->route('products.index')
                        ->with('success','Product deleted successfully');
    }
}

ก็อปโค้ดต่อไปทั้งหมดนี้ลงในไฟล์ app/Product.php

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'detail'
    ];
}


Step 6: Create Blade Files

สร้างไฟล์ blade เพื่อทำ layout หน้าตาเพจแต่ละส่วน ก่อนอื่น ให้สร้าง โฟลเดอร์ชื่อ "products" ใน resources/views/ แล้วสร้างไฟล์ใหม่ต่อไปนี้ใน  resources/views/products
  1. layout.blade.php : เป็นโครงสร้างหลักของหน้าเว็บ 
  2. index.blade.php : หน้าหลักที่แสดงตารางรายการ products ทั้งหมด
  3. show.blade.php : หน้าแสดงข้อมูลแต่ละรายการ
  4. create.blade.php : หน้าเพิ่มรายการ
  5. edit.blade.php : หน้าแก้ไขแต่ละรายการ

1) resources/views/products/layout.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 5.6 CRUD Application</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.css" rel="stylesheet">
</head>
<body>

<div class="container">
    @yield('content')
</div>

</body>
</html>

2) resources/views/products/index.blade.php

@extends('products.layout')

@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Laravel 5.6 CRUD Example from scratch</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-success" href="{{ route('products.create') }}"> Create New Product</a>
            </div>
        </div>
    </div>

    @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
    @endif

    <table class="table table-bordered">
        <tr>
            <th>No</th>
            <th>Name</th>
            <th>Details</th>
            <th width="280px">Action</th>
        </tr>
        @foreach ($products as $product)
        <tr>
            <td>{{ ++$i }}</td>
            <td>{{ $product->name }}</td>
            <td>{{ $product->detail }}</td>
            <td>
                <form action="{{ route('products.destroy',$product->id) }}" method="POST">
                    <a class="btn btn-info" href="{{ route('products.show',$product->id) }}">Show</a>
                    <a class="btn btn-primary" href="{{ route('products.edit',$product->id) }}">Edit</a>

                    @csrf
                    @method('DELETE')

                    <button type="submit" class="btn btn-danger">Delete</button>
                </form>
            </td>
        </tr>
        @endforeach
    </table>

    {!! $products->links() !!}

@endsection

3) resources/views/products/show.blade.php

@extends('products.layout')

@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2> Show Product</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                {{ $product->name }}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Details:</strong>
                {{ $product->detail }}
            </div>
        </div>
    </div>
@endsection

4) resources/views/products/create.blade.php

@extends('products.layout')

@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Add New Product</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
            </div>
        </div>
    </div>

    @if ($errors->any())
        <div class="alert alert-danger">
            <strong>Whoops!</strong> There were some problems with your input.<br><br>
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif

    <form action="{{ route('products.store') }}" method="POST">
        @csrf

         <div class="row">
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Name:</strong>
                    <input type="text" name="name" class="form-control" placeholder="Name">
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Detail:</strong>
                    <textarea class="form-control" style="height:150px" name="detail" placeholder="Detail"></textarea>
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12 text-center">
                    <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </div>
    </form>

@endsection

5) resources/views/products/edit.blade.php

@extends('products.layout')

@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Edit Product</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
            </div>
        </div>
    </div>

    @if ($errors->any())
        <div class="alert alert-danger">
            <strong>Whoops!</strong> There were some problems with your input.<br><br>
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif

    <form action="{{ route('products.update',$product->id) }}" method="POST">
        @csrf
        @method('PUT')

         <div class="row">
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Name:</strong>
                    <input type="text" name="name" value="{{ $product->name }}" class="form-control" placeholder="Name">
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Detail:</strong>
                    <textarea class="form-control" style="height:150px" name="detail" placeholder="Detail">{{ $product->detail }}</textarea>
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12 text-center">
              <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </div>
    </form>

@endsection

Download Full Script


Previous
Next Post »