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



Checkpoint
Pastikan:
- CRUD kriteria berjalan;
- bobot tersimpan;
- atribut
benefit/costtersimpan; - CRUD alternatif berjalan;
- perubahan data mengosongkan ranking lama.




