Bagian 2 dari seri

CRUD Kriteria dan Alternatif SAW Laravel

Diterbitkan 21 September 2026

Pada bagian ini buat CRUD kriteria dan alternatif. Kriteria memiliki bobot dan atribut.

Gunakan benefit jika nilai besar lebih baik, dan cost jika nilai kecil lebih baik.

Buat Controller

php artisan make:controller KriteriaController --resource
php artisan make:controller AlternatifController --resource

Route

Tambahkan ke grup middleware auth:

use App\Http\Controllers\AlternatifController;
use App\Http\Controllers\KriteriaController;

Route::resource(
    'kriteria',
    KriteriaController::class
)
    ->except('show')
    ->parameters(['kriteria' => 'kriteria']);

Route::resource(
    'alternatif',
    AlternatifController::class
)->except('show');

KriteriaController

app/Http/Controllers/KriteriaController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Alternatif;
use App\Models\Kriteria;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class KriteriaController extends Controller
{
    public function index()
    {
        $items = Kriteria::orderBy('kode')->get();

        return view('kriteria.index', compact('items'));
    }

    public function create()
    {
        return view('kriteria.form', [
            'item' => new Kriteria(),
        ]);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'kode' => [
                'required',
                'max:10',
                'unique:kriteria,kode',
            ],
            'nama' => [
                'required',
                'max:255',
            ],
            'bobot' => [
                'required',
                'numeric',
                'gt:0',
            ],
            'atribut' => [
                'required',
                Rule::in(['benefit', 'cost']),
            ],
        ]);

        Kriteria::create($data);

        $this->resetHasil();

        return redirect()
            ->route('kriteria.index')
            ->with(
                'success',
                'Kriteria berhasil ditambahkan.'
            );
    }

    public function edit(Kriteria $kriteria)
    {
        return view('kriteria.form', [
            'item' => $kriteria,
        ]);
    }

    public function update(
        Request $request,
        Kriteria $kriteria
    ) {
        $data = $request->validate([
            'kode' => [
                'required',
                'max:10',
                Rule::unique('kriteria', 'kode')
                    ->ignore($kriteria->id),
            ],
            'nama' => [
                'required',
                'max:255',
            ],
            'bobot' => [
                'required',
                'numeric',
                'gt:0',
            ],
            'atribut' => [
                'required',
                Rule::in(['benefit', 'cost']),
            ],
        ]);

        $kriteria->update($data);

        $this->resetHasil();

        return redirect()
            ->route('kriteria.index')
            ->with(
                'success',
                'Kriteria berhasil diperbarui.'
            );
    }

    public function destroy(Kriteria $kriteria)
    {
        $kriteria->delete();

        $this->resetHasil();

        return redirect()
            ->route('kriteria.index')
            ->with(
                'success',
                'Kriteria berhasil dihapus.'
            );
    }

    private function resetHasil(): void
    {
        Alternatif::query()->update([
            'nilai_preferensi' => null,
            'ranking' => null,
        ]);
    }
}

View Daftar Kriteria

resources/views/kriteria/index.blade.php:

@extends('layouts.app')

@section('title', 'Kriteria')

@section('content')
<div class="d-flex justify-content-between align-items-center mb-3">
    <h2 class="h4 mb-0">Kriteria</h2>

    <a
        href="{{ route('kriteria.create') }}"
        class="btn btn-primary">
        Tambah Kriteria
    </a>
</div>

<div class="card border-0 shadow-sm">
    <div class="card-body">
        <div class="table-responsive">
            <table class="table table-bordered align-middle mb-0">
                <thead>
                <tr>
                    <th>Kode</th>
                    <th>Nama</th>
                    <th>Bobot</th>
                    <th>Atribut</th>
                    <th width="160">Aksi</th>
                </tr>
                </thead>

                <tbody>
                @forelse($items as $item)
                    <tr>
                        <td>{{ $item->kode }}</td>
                        <td>{{ $item->nama }}</td>
                        <td>{{ $item->bobot }}</td>
                        <td>{{ ucfirst($item->atribut) }}</td>
                        <td>
                            <a
                                href="{{ route('kriteria.edit', $item) }}"
                                class="btn btn-warning btn-sm">
                                Edit
                            </a>

                            <form
                                method="POST"
                                action="{{ route('kriteria.destroy', $item) }}"
                                class="d-inline"
                                onsubmit="return confirm('Hapus data?')">
                                @csrf
                                @method('DELETE')

                                <button class="btn btn-danger btn-sm">
                                    Hapus
                                </button>
                            </form>
                        </td>
                    </tr>
                @empty
                    <tr>
                        <td colspan="5" class="text-center">
                            Belum ada data.
                        </td>
                    </tr>
                @endforelse
                </tbody>
            </table>
        </div>
    </div>
</div>
@endsection

Form Kriteria

resources/views/kriteria/form.blade.php:

@extends('layouts.app')

@section(
    'title',
    $item->exists ? 'Edit Kriteria' : 'Tambah Kriteria'
)

@section('content')
<div class="card border-0 shadow-sm">
    <div class="card-body">
        <h2 class="h4 mb-4">
            {{ $item->exists ? 'Edit Kriteria' : 'Tambah Kriteria' }}
        </h2>

        <form
            method="POST"
            action="{{ $item->exists
                ? route('kriteria.update', $item)
                : route('kriteria.store') }}">

            @csrf

            @if($item->exists)
                @method('PUT')
            @endif

            <div class="mb-3">
                <label class="form-label">Kode</label>

                <input
                    type="text"
                    name="kode"
                    value="{{ old('kode', $item->kode) }}"
                    class="form-control"
                    required>
            </div>

            <div class="mb-3">
                <label class="form-label">Nama Kriteria</label>

                <input
                    type="text"
                    name="nama"
                    value="{{ old('nama', $item->nama) }}"
                    class="form-control"
                    required>
            </div>

            <div class="mb-3">
                <label class="form-label">Bobot</label>

                <input
                    type="number"
                    name="bobot"
                    value="{{ old('bobot', $item->bobot) }}"
                    class="form-control"
                    step="0.000001"
                    min="0.000001"
                    required>
            </div>

            <div class="mb-3">
                <label class="form-label">Atribut</label>

                <select
                    name="atribut"
                    class="form-select"
                    required>

                    <option value="">Pilih atribut</option>

                    <option
                        value="benefit"
                        @selected(
                            old('atribut', $item->atribut) === 'benefit'
                        )>
                        Benefit
                    </option>

                    <option
                        value="cost"
                        @selected(
                            old('atribut', $item->atribut) === 'cost'
                        )>
                        Cost
                    </option>
                </select>
            </div>

            <button class="btn btn-primary">
                Simpan
            </button>

            <a
                href="{{ route('kriteria.index') }}"
                class="btn btn-secondary">
                Kembali
            </a>
        </form>
    </div>
</div>
@endsection

AlternatifController

app/Http/Controllers/AlternatifController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Alternatif;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class AlternatifController extends Controller
{
    public function index()
    {
        $items = Alternatif::orderBy('kode')->get();

        return view('alternatif.index', compact('items'));
    }

    public function create()
    {
        return view('alternatif.form', [
            'item' => new Alternatif(),
        ]);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'kode' => [
                'required',
                'max:10',
                'unique:alternatif,kode',
            ],
            'nama' => [
                'required',
                'max:255',
            ],
        ]);

        Alternatif::create($data);

        $this->resetHasil();

        return redirect()
            ->route('alternatif.index')
            ->with(
                'success',
                'Alternatif berhasil ditambahkan.'
            );
    }

    public function edit(Alternatif $alternatif)
    {
        return view('alternatif.form', [
            'item' => $alternatif,
        ]);
    }

    public function update(
        Request $request,
        Alternatif $alternatif
    ) {
        $data = $request->validate([
            'kode' => [
                'required',
                'max:10',
                Rule::unique('alternatif', 'kode')
                    ->ignore($alternatif->id),
            ],
            'nama' => [
                'required',
                'max:255',
            ],
        ]);

        $alternatif->update($data);

        $this->resetHasil();

        return redirect()
            ->route('alternatif.index')
            ->with(
                'success',
                'Alternatif berhasil diperbarui.'
            );
    }

    public function destroy(Alternatif $alternatif)
    {
        $alternatif->delete();

        $this->resetHasil();

        return redirect()
            ->route('alternatif.index')
            ->with(
                'success',
                'Alternatif berhasil dihapus.'
            );
    }

    private function resetHasil(): void
    {
        Alternatif::query()->update([
            'nilai_preferensi' => null,
            'ranking' => null,
        ]);
    }
}

View Daftar Alternatif

resources/views/alternatif/index.blade.php:

@extends('layouts.app')

@section('title', 'Alternatif')

@section('content')
<div class="d-flex justify-content-between align-items-center mb-3">
    <h2 class="h4 mb-0">Alternatif</h2>

    <a
        href="{{ route('alternatif.create') }}"
        class="btn btn-primary">
        Tambah Alternatif
    </a>
</div>

<div class="card border-0 shadow-sm">
    <div class="card-body">
        <div class="table-responsive">
            <table class="table table-bordered align-middle mb-0">
                <thead>
                <tr>
                    <th>Kode</th>
                    <th>Nama</th>
                    <th width="160">Aksi</th>
                </tr>
                </thead>

                <tbody>
                @forelse($items as $item)
                    <tr>
                        <td>{{ $item->kode }}</td>
                        <td>{{ $item->nama }}</td>
                        <td>
                            <a
                                href="{{ route('alternatif.edit', $item) }}"
                                class="btn btn-warning btn-sm">
                                Edit
                            </a>

                            <form
                                method="POST"
                                action="{{ route('alternatif.destroy', $item) }}"
                                class="d-inline"
                                onsubmit="return confirm('Hapus data?')">
                                @csrf
                                @method('DELETE')

                                <button class="btn btn-danger btn-sm">
                                    Hapus
                                </button>
                            </form>
                        </td>
                    </tr>
                @empty
                    <tr>
                        <td colspan="3" class="text-center">
                            Belum ada data.
                        </td>
                    </tr>
                @endforelse
                </tbody>
            </table>
        </div>
    </div>
</div>
@endsection

Form Alternatif

resources/views/alternatif/form.blade.php:

@extends('layouts.app')

@section(
    'title',
    $item->exists ? 'Edit Alternatif' : 'Tambah Alternatif'
)

@section('content')
<div class="card border-0 shadow-sm">
    <div class="card-body">
        <h2 class="h4 mb-4">
            {{ $item->exists ? 'Edit Alternatif' : 'Tambah Alternatif' }}
        </h2>

        <form
            method="POST"
            action="{{ $item->exists
                ? route('alternatif.update', $item)
                : route('alternatif.store') }}">

            @csrf

            @if($item->exists)
                @method('PUT')
            @endif

            <div class="mb-3">
                <label class="form-label">Kode</label>

                <input
                    type="text"
                    name="kode"
                    value="{{ old('kode', $item->kode) }}"
                    class="form-control"
                    required>
            </div>

            <div class="mb-3">
                <label class="form-label">Nama Alternatif</label>

                <input
                    type="text"
                    name="nama"
                    value="{{ old('nama', $item->nama) }}"
                    class="form-control"
                    required>
            </div>

            <button class="btn btn-primary">
                Simpan
            </button>

            <a
                href="{{ route('alternatif.index') }}"
                class="btn btn-secondary">
                Kembali
            </a>
        </form>
    </div>
</div>
@endsection

Tambahkan Menu

Pada navbar tambahkan:

<a
    class="nav-link text-white"
    href="{{ route('kriteria.index') }}">
    Kriteria
</a>

<a
    class="nav-link text-white"
    href="{{ route('alternatif.index') }}">
    Alternatif
</a>

Contoh

Gunakan data:

Harga      = cost
Kualitas   = benefit
Pelayanan  = benefit
Tutorial Saw Laravel Kriteria
Tutorial Saw Laravel Kriteria Tambah
Tutorial Saw Laravel Alternatif

Checkpoint

Pastikan:

  • CRUD kriteria berjalan;
  • bobot tersimpan;
  • atribut benefit/cost tersimpan;
  • CRUD alternatif berjalan;
  • perubahan data mengosongkan ranking lama.

Lanjut: Input Nilai Alternatif SAW