MEMBUAT POST PADA LARAVEL 3.1.8
LANGSUNG LOMPAT KE TOPIK SEEDER (SETTING DULU SBB):
CONTROLLERS > POST CONTROLLER
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
class PostController extends Controller
{
public function index()
{
return view('posts', [
"title" => "All Posts",
"posts" => Post::latest()->filter(request(['search', 'category', 'author']))->paginate(5)->withQueryString()
]);
}
public function show(Post $post)
{
return view('post', [
"title" => "Single Post",
"post" => $post
]);
}
}
MODELS > CATEGORY
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $guarded = ['id'];
public function posts()
{
return $this->hasMany(Post::class);
}
}
MODELS > POST
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $guarded = ['id'];
protected $with = ['category', 'author'];
public function scopeFilter($query, array $filters)
{
$query->when($filters['search'] ?? false, function($query, $search) {
return $query->where('title', 'like', '%' . $search . '%')
->orwhere('body', 'like', '%' . $search . '%');
});
$query->when($filters['category'] ?? false, function($query, $category) {
return $query->whereHas('category', function($query) use ($category) {
$query->where('slug', $category);
});
});
$query->when($filters['author'] ?? false, fn($query, $author) =>
$query->whereHas('author', fn($query) =>
$query->where('username', $author)
)
);
}
public function category()
{
return $this->belongsTo(Category::class);
}
public function author()
{
return $this->belongsTo(User::class, 'user_id');
}
}
MODELS > USER
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function posts()
{
return $this->hasMany(Post::class);
}
}
MIGRATIONS - CATEGORIES
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('slug')->unique();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
};
MIGRATIONS - POSTS
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('category_id');
$table->foreignId('user_id');
$table->string('title');
$table->string('slug')->unique();
$table->text('excerpt');
$table->text('body');
$table->timestamp('published_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
MIGRATIONS - USERS
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// BEGIN
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->boolean('is_admin')->default(false);
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
// END
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
VIEWS > CATEGORIES
@extends('layouts.main')@extends('layouts.main')
@section('container')
@include('layouts.nav2')
<section>
<div class="container mt-5">
<h1 class=mb-5>Post Categories</h1>
@foreach ($categories as $category)
<ul>
<li>
<h2>
<a href="/categories/{{ $category->slug }}">{{ $category->name }}</a>
</h2>
</li>
</ul>
@endforeach
</div>
</section>
@endsection
VIEWS > POSTS
@extends('layouts.main')('container')
@extends('layouts.main')
@include('layouts.nav2')
@section('container')
<section>
<div class="container mt-5">
<h3>{{ $title }}</h3>
@if ($posts->count())
<div class="card mb-5">
<img src="https://source.unsplash.com/540x230?{{ $posts[0]->category->name }}" class="card-img-top" alt="{{ $posts[0]->category->name }}">
<div class="card-body">
<h1 class="card-title"><a href="/posts/{{ $posts[0]->slug }}" class="text-decoration-none text-dark"> {{ $posts[0]->title }}</a></h1>
<p>By: <a href="/posts?author={{ $posts[0]->author->username }}" class="text-decoration-none">{{ $posts[0]->author->name }}</a> in <a href="/posts?category={{ $posts[0]->category->slug }}" class="text-decoration-none">{{ $posts[0]->category->name }}</a></p>
<p class="card-text">{{ $posts[0]->excerpt }}</p>
<p class="card-text"><small class="text-muted">Last updated {{ $posts[0]->created_at->diffForHumans() }}</small></p>
<a href="/posts/{{ $posts[0]->slug }}" class="text-decoration-none btn btn-primary">Read More</a>
</div>
</div>
<div class="container">
<div class="row">
@foreach ($posts->skip(1) as $post)
<div class="col-md-6 mb-5">
<div class="card">
<img src="https://source.unsplash.com/540x330?{{ $post->category->name }}" class="card-img-top" alt="{{ $post->category->name }}">
<div class="card-body">
<h1 class="card-title"><a href="/posts/{{ $post->slug }}" class="text-decoration-none text-dark">{{ $post->title }}</a></h1>
<p>By: <a href="/posts?author={{ $post->author->username }}" class="text-decoration-none">{{ $post->author->name }}</a><br>in <small class="text-muted"><a href="/posts?category={{ $post->category->slug }}" class="text-decoration-none">{{ $post->category->name }}</a></p><p> Last updated {{ $post->created_at->diffForHumans() }}</small></p>
<p class="card-text">{{ $post->excerpt }}</p>
<a href="/posts/{{ $post->slug }}" class="text-decoration-none btn btn-primary">Read More</a>
</div>
</div>
</div>
@endforeach
</div>
</div>
{{-- @foreach ($posts->skip(1) as $post)
<article class="mt-5 border-bottom mb-5 pb-4">
<h2>
<a href="/posts/{{ $post->slug }}" class="text-decoration-none">{{ $post->title }}</a>
</h2>
<p>By: <a href="/author/{{ $post->author->username }}" class="text-decoration-none">{{ $post->author->name }}</a> in <a href="/categories/{{ $post->category->slug }}" class="text-decoration-none">{{ $post->category->name }}</a></p>
<p>{{ $post->excerpt }}</p>
<a href="/posts/{{ $post->slug }}" class="text-decoration-none">Read More.</a>
</article>
@endforeach --}}
</div>
</section>
@else
<p class="text-center mt-5 fs-1">404<br class="fs-2">- File Not Found</p>
@endif
{{ $posts->links() }}
@endsection
VIEWS > POST
@extends('layouts.main')@extends('layouts.main')
@include('Layouts.nav2')
@section('container')
<section>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<h3 class="mt-5 mb-5">Single Post</h3>
<h1 class="mb-3">{{ $post->title }}</h1>
<p>By: <a href="/posts?author={{ $post->author->username }}" class="text-decoration-none">{{ $post->author->name }}</a> in <a href="/posts?category={{ $post->category->slug }}" class="text-decoration-none">{{ $post->category->name }}</a></p>
<img src="https://source.unsplash.com/1200x630?{{ $post->category->name }}" alt="{{ $post->category->name }}" class="img-fluid">
<article class="my-4 fs-5">
{!! $post->body !!}
</article>
<a href="/posts" class="d-block pt-4 text-decoration-none">Back To Posts</a>
</div>
</div>
</div>
{{-- <div class="container mt-5">
<h3 class="mb-5">Single Post</h3>
<h1 class="mb-5">{{ $post->title }}</h1>
<p>By: <a href="/author/{{ $post->author->username }}" class="text-decoration-none">{{ $post->author->name }}</a> in <a href="/categories/{{ $post->category->slug }}" class="text-decoration-none">{{ $post->category->name }}</a></p>
{!! $post->body !!}
<a href="/posts" class="d-block pt-4 text-decoration-none">Back To Posts</a>
</div> --}}
</section>
@endsection
ROUTES
<?php
use Illuminate\Support\Facades\Route;
use App\Models\Post;
use App\Http\Controllers\PostController;
use App\Models\Category;
use App\Models\User;
/*
|--------------------------------------------------------------------------
| 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('home', [
"title" => "Home"
]);
});
Route::get('/data', function () {
return view('data', [
"title" => "Data"
]);
});
Route::get('/posts', [PostController::class, 'index']);
Route::get('posts/{post:slug}', [PostController::class, 'show']);
Route::get('categories', function() {
return view('categories', [
'title' => 'Post Categories',
'categories' => Category::all()
]);
});
Route::get('categories/{category:slug}', function(Category $category) {
return view('posts', [
'title' => "Post By Category : $category->name",
'posts' => $category->posts->load('category', 'author')
]);
});
Route::get('/author/{author:username}', function(User $author) {
return view('posts', [
'title' => "Post By Author : $author->name",
'posts' => $author->posts->load('category', 'author')
]);
});
DATABASE SEEDER
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Category;
use App\Models\Post;
*NOTES: SEBAIKNYA DIKETIK LANGSUNG BUKAN COPAS, UNTUK LATIHAN KETELITIAN DAN KECERMATAN.
UNTUK FACTORY NYUSUL.
TAMBAHKAN USERNAME PADA USER FACTORY
public function definition()
{
return [
'name' => fake()->name(),
'username' => fake()->unique()->userName(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
0 Reviews:
Posting Komentar