CRUD Gambar Laravel 8

CRUD Gambar Laravel 8 – Tutorial Create, Read, Update, dan Delete Gambar Laravel 8 dan MySQL. Pada tutorial ini, menggunakan kasus mengolah data posting (artikel). Pada artikel sebelumnya sudah membahas tentang Crud User Laravel 8.

Membuat Project Laravel

Pastikan Anda sudah menginstall composer, kemudian jalankan perintah berikut di command prompt.

composer create-project laravel/laravel laravel-crud-gambar

Mengatur Database MySQL

Buat database dengan nama laravel_crud_gambar di http://localhost/phpmyadmin jika Anda menginstall XAMPP untuk server MySQL.

Sesuaikan pengaturan koneksi mysql di project laravel pada file .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_crud_gambar
DB_USERNAME=root
DB_PASSWORD=

Sesuaikan DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, dan DB_PASSWORD sesuai server MySQL.

Membuat Migration Post

Buat migration untuk tb_post dengan perintah berikut.

php artisan make:migration create_post_table --create=tb_post

Kemudian sesuaikan field pada post migration yang ada di direktori database/migrations sebagai berikut

<?php

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

class CreatePostTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tb_post', function (Blueprint $table) {
            $table->id('post_id');
            $table->string('post_title');
            $table->string('category');
            $table->string('image')->nullable();
            $table->text('content')->nullable();
            $table->timestamps();
        });

        /** gunakan script berikut jika ingin menambah data otomatis */
        $categories = ['Politik', 'Kesehatan', 'Olahraga'];
        for ($a = 1; $a <= 15; $a++)
            DB::table('tb_post')->insert([
                'post_title' => 'Judul Artikel ' . $a,
                'category' => $categories[array_rand($categories)],
            ]);
    }

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

Perintah insert berfungsi untuk menambahkan data post langsung ketika selesai membuat tabel.

Lakukan migration dengan mengetikan perintah berikut.

php artisan migrate

Setelah berhasil menjalankan perintah migrate, maka di database akan ada tabel tb_post berisi 15 data.

Membuat Model Post

Buat model Post menggunakan perintah berikut.

php artisan make:model Post

Sesuaikan app/models/Post.php sebagai berikut.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $table = 'tb_post';
    protected $primaryKey = 'post_id';

    protected $fillable = [
        'post_title',
        'category',
        'image',
        'content',
    ];

    function image()
    {
        if ($this->image && file_exists(public_path('images/post/' . $this->image)))
            return asset('images/post/' . $this->image);
        else
            return asset('images/no_image.png');
    }

    function delete_image()
    {
        if ($this->image && file_exists(public_path('images/post/' . $this->image)))
            return unlink(public_path('images/post/' . $this->image));
    }
}

Properti $table untuk mengatur nama tabel di database, jika nama tabel anda posts, tidak usah mengubah properti ini.

Properti $primaryKey untuk mengatur PRIMARY KEY di tabel post, jika primary key anda id, tidak usah mengubah properti ini.

Properti $fillable untuk mengatur field apa saja yang bisa diinput/ubah ketika melakukan crud di tabel post.

Membuat Controller Post Tipe Resource

Gunakan perintah berikut untuk membuat controller resource sekaligus mengatur model menjadi Post.

php artisan make:controller PostController --resource --model=Post

Sesuaikan app/controllers/PostController.php sebagai berikut.

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $data['title'] = 'Data Post';
        $data['q'] = $request->q;
        $data['rows'] = Post::where('post_title', 'like', '%' . $request->q . '%')->get();
        return view('post.index', $data);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Request $request)
    {
        $data['title'] = 'Tambah Post';
        $data['categories'] = ['Politik', 'Kesehatan', 'Olahraga'];
        return view('post.create', $data);
    }

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

        $post = new Post();
        $post->post_title = $request->post_title;
        $post->category = $request->category;
        if ($request->hasFile('image')) {
            $image = $request->file('image');
            $name = rand(1000, 9999) . $image->getClientOriginalName();
            $image->move('images/post', $name);
            $post->image = $name;
        }
        $post->content = $request->content;
        $post->save();
        return redirect('post')->with('success', 'Tambah Data Berhasil');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        $data['title'] = 'Ubah Post';
        $data['row'] = $post;
        $data['categories'] = ['Politik', 'Kesehatan', 'Olahraga'];
        return view('post.edit', $data);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        $request->validate([
            'post_title' => 'required',
            'category' => 'required',
        ]);

        $post->post_title = $request->post_title;
        $post->category = $request->category;
        if ($request->hasFile('image')) {
            $post->delete_image();
            $image = $request->file('image');
            $name = rand(1000, 9999) . $image->getClientOriginalName();
            $image->move('images/post', $name);
            $post->image = $name;
        }
        $post->content = $request->content;
        $post->save();
        return redirect('post')->with('success', 'Ubah Data Berhasil');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        $post->delete_image();
        $post->delete();
        return redirect('post')->with('success', 'Hapus Data Berhasil');
    }
}

Menambahkan Route Post

Tambahkan route untuk crud post di routes/web.php bertipe resource seperti berikut.

<?php

use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::resource('post', PostController::class);

Membuat View

View Template

Buat view untuk template di direktori resources/views/app.blade.php.

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css">
    <title>@yield('title', $title)</title>
</head>

<body>
    <div class="container">
        <h1>@yield('title', $title)</h1>
        @yield('content')
    </div>
</body>

</html>

View Tampil

Buat view untuk menampilkan data post di direktori resources/views/post/index.blade.php.

@extends('app')
@section('content')
@if(session('success'))
<p class="alert alert-success">{{ session('success') }}</p>
@endif
<div class="card card-default">
    <div class="card-header">
        <form class="form-inline">
            <div class="form-group mr-1">
                <input class="form-control" type="text" name="q" value="{{ $q}}" placeholder="Pencarian..." />
            </div>
            <div class="form-group mr-1">
                <button class="btn btn-success">Refresh</button>
            </div>
            <div class="form-group mr-1">
                <a class="btn btn-primary" href="{{ route('post.create') }}">Tambah</a>
            </div>
        </form>
    </div>
    <div class="card-body p-0 table-responsive">
        <table class="table table-bordered table-striped table-hover mb-0">
            <thead>
                <tr>
                    <th>No</th>
                    <th>Judul</th>
                    <th>Kategori</th>
                    <th>Gambar</th>
                    <th>Aksi</th>
                </tr>
            </thead>
            <?php $no = 1 ?>
            @foreach($rows as $row)
            <tr>
                <td>{{ $no++ }}</td>
                <td>{{ $row->post_title }}</td>
                <td>{{ $row->category }}</td>
                <td>
                    <img src="{{ $row->image() }}" height="75" />
                </td>
                <td>
                    <a class="btn btn-sm btn-warning" href="{{ route('post.edit', $row) }}">Ubah</a>
                    <form method="POST" action="{{ route('post.destroy', $row) }}" style="display: inline-block;">
                        @csrf
                        @method('DELETE')
                        <button class="btn btn-sm btn-danger" onclick="return confirm('Hapus Data?')">Hapus</button>
                    </form>
                </td>
            </tr>
            @endforeach
        </table>
    </div>
</div>
@endsection

View Tambah

Buat view untuk menambah data post di direktori resources/views/post/create.blade.php.

@extends('app')
@section('content')
<div class="row">
    <div class="col-md-6">
        @if($errors->any())
        @foreach($errors->all() as $err)
        <p class="alert alert-danger">{{ $err }}</p>
        @endforeach
        @endif
        <form action="{{ route('post.store') }}" method="POST" enctype="multipart/form-data">
            @csrf
            <div class="form-group">
                <label>Judul <span class="text-danger">*</span></label>
                <input class="form-control" type="text" name="post_title" value="{{ old('post_title') }}" />
            </div>
            <div class="form-group">
                <label>Kategori <span class="text-danger">*</span></label>
                <select class="form-control" name="category" />
                @foreach($categories as $category)
                @if($category==old('category'))
                <option value="{{ $category }}" selected>{{ $category }}</option>
                @else
                <option value="{{ $category }}">{{ $category }}</option>
                @endif
                @endforeach
                </select>
            </div>
            <div class="form-group">
                <label>Gambar</label>
                <input class="form-control" type="file" name="image" value="{{ old('image') }}" />
            </div>
            <div class="form-group">
                <label>Isi</label>
                <textarea class="form-control" name="content" rows="10">{{ old('content') }}</textarea>
            </div>
            <div class="form-group">
                <button class="btn btn-primary">Simpan</button>
                <a class="btn btn-danger" href="{{ route('post.index') }}">Kembali</a>
            </div>
        </form>
    </div>
</div>
@endsection

View Ubah

Buat view untuk menambah data post di direktori resources/views/post/edit.blade.php.

@extends('app')
@section('content')
<div class="row">
    <div class="col-md-6">
        @if($errors->any())
        @foreach($errors->all() as $err)
        <p class="alert alert-danger">{{ $err }}</p>
        @endforeach
        @endif
        <form action="{{ route('post.update', $row) }}" method="POST" enctype="multipart/form-data">
            @csrf
            @method('PUT')
            <div class="form-group">
                <label>Judul <span class="text-danger">*</span></label>
                <input class="form-control" type="text" name="post_title" value="{{ old('post_title', $row->post_title) }}" />
            </div>
            <div class="form-group">
                <label>Kategori <span class="text-danger">*</span></label>
                <select class="form-control" name="category" />
                @foreach($categories as $category)
                @if($category==old('category', $row->category))
                <option value="{{ $category }}" selected>{{ $category }}</option>
                @else
                <option value="{{ $category }}">{{ $category }}</option>
                @endif
                @endforeach
                </select>
            </div>
            <div class="form-group">
                <label>Gambar</label>
                <input class="form-control" type="file" name="image" value="{{ old('image') }}" />
                <p class="form-text">Kosongkan jika tidak ingin mengubah gambar.</p>
                <img src="{{ $row->image() }}" height="75" />
            </div>
            <div class="form-group">
                <label>Isi</label>
                <textarea class="form-control" name="content" rows="10">{{ old('content', $row->content) }}</textarea>
            </div>
            <div class="form-group">
                <button class="btn btn-primary">Simpan</button>
                <a class="btn btn-danger" href="{{ route('post.index') }}">Kembali</a>
            </div>
        </form>
    </div>
</div>
@endsection

Menjalankan Crud Gambar Laravel 8

Silahkan gunakan perintah berikut untuk mengaktifkan server laravel.

php artisan serve

Ketikkan alamat sesuai server diikuti dengan /post di browser (http://127.0.0.1:8000/post). Hasilnya seperti berikut.

Tampil Post
Tambah Post
Ubah Post

Itulah tutorial membuat CRUD gambar laravel 8. Jika ada yang ditanyakan, silahkan berkomentar.

8 thoughts on “CRUD Gambar Laravel 8

  • 12 Juli 2021 pada 10:53 am
    Permalink

    File view untuk view tampil ke bawah tidak ada ya?

    Balas
    • 12 Juli 2021 pada 11:08 am
      Permalink

      Maaf ketinggalan, silahkan cek lagi.

      Balas
      • 12 Juli 2021 pada 4:52 pm
        Permalink

        Oke, thanks. Satu lagi, sepertinya ada fungsi yang hilang di Model Post.php, fungsi delete_image tidak ada, barangkali perlu dicek.

        Terimakasih

        Balas
        • 12 Juli 2021 pada 7:14 pm
          Permalink

          Baik, sudah saya update. Terimakasih atas koreksinya.

          Balas
  • 21 Juli 2021 pada 3:56 pm
    Permalink

    min, jika function image() yang dipanggil di view mendapatkan eror seperti ini
    “Call to undefined method stdClass”
    itu bagaimana ya

    Balas
    • 21 Juli 2021 pada 4:00 pm
      Permalink

      Itu berarti belum ditambahkan method image di Model Post.
      function image()
      {
      if ($this->image && file_exists(public_path(‘images/post/’ . $this->image)))
      return asset(‘images/post/’ . $this->image);
      else
      return asset(‘images/no_image.png’);
      }

      Balas
      • 21 Juli 2021 pada 8:03 pm
        Permalink

        sudah ditambahkan min, pada modelnya. sesuai dengan tutorial yang admin tulis diatas.

        sama untuk line code ini row diambil dari mana ya min?
        $data[‘rows’] = Post::where(‘post_title’, ‘like’, ‘%’ . $request->q . ‘%’)->get();

        sama yang ini apa beda nya min row dengan ‘s’ dan row tanpa ‘s’
        $data[‘row’] = $post;

        Balas
        • 21 Juli 2021 pada 8:50 pm
          Permalink

          Row itu hanya sebuah penamaan variabel untuk 1 baris data, bebas bisa diganti, yang jelas nanti sesuaikan di view ketika memanggil datanya. Untuk rows itu menampilkan banyak baris data post untuk halaman tampil post, kalau row hanya 1 baris data post saja untuk ubah atau hapus.

          Balas

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.