7、Laravel 11 模型查询
一般,发布的文章都有一个类型,而类型与文章之间又是一个一对多的关系,即一分类下可以有很多篇文章。本篇文章就来完善我们的 Bolg。
文章迁移文件
1、创建文章迁移文件
$ php artisan make:migration "craete posts table"
2、编写迁移文件
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('category_id')->default(0)->index()->comment('分类 ID');
$table->string('title')->index()->comment('文章标题');
$table->text('text')->comment('文章内容');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
3、执行迁移文件
$ php artisan migrate
为了接下来的效果演示,请大家收手动为文章表添加一些数据吧。
模型查询
1、创建模型
$ php artisan make:model Post
2、控制器获取文章
app/Http/Controllers/HomeController.php
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Post;
class HomeController extends Controller
{
public function index()
{
// 分类
$categories = Category::all();
// 获取所有文章
$posts = Post::latest()->get();
return view('home', compact('categories', 'posts'));
}
}
3、视图显示文章
resources/views/home.blade.php
@extends('layouts.app')
@section('content')
<!-- Page header with logo and tagline-->
<header class="py-5 bg-light border-bottom mb-4">
<div class="container">
<div class="text-center my-5">
<h1 class="fw-bolder">一方天地!</h1>
<p class="lead mb-0">嗨,我是王美丽</p>
</div>
</div>
</header>
<div class="container">
<div class="row">
<!-- Blog entries-->
<div class="col-lg-8">
<!-- Nested row for non-featured blog posts-->
<div class="row">
@foreach($posts as $post)
<div class="col-lg-6">
<!-- Blog post-->
<div class="card mb-4">
<a href="#!"><img class="card-img-top" src="https://dummyimage.com/700x350/dee2e6/6c757d.jpg" alt="..." /></a>
<div class="card-body">
<div class="small text-muted">{{ $post->created_at }}</div>
<h2 class="card-title h4">{{ $post->title }}</h2>
<p class="card-text">{{ $post->text }}</p>
<a class="btn btn-primary" href="#!">Read more →</a>
</div>
</div>
</div>
@endforeach
</div>
<!-- Pagination-->
<nav aria-label="Pagination">
<hr class="my-0" />
<ul class="pagination justify-content-center my-4">
<li class="page-item disabled"><a class="page-link" href="#" tabindex="-1" aria-disabled="true">Newer</a></li>
<li class="page-item active" aria-current="page"><a class="page-link" href="#!">1</a></li>
<li class="page-item"><a class="page-link" href="#!">2</a></li>
<li class="page-item"><a class="page-link" href="#!">3</a></li>
<li class="page-item disabled"><a class="page-link" href="#!">...</a></li>
<li class="page-item"><a class="page-link" href="#!">15</a></li>
<li class="page-item"><a class="page-link" href="#!">Older</a></li>
</ul>
</nav>
</div>
<!-- Side widgets-->
<div class="col-lg-4">
<!-- Search widget-->
<div class="card mb-4">
<div class="card-header">Search</div>
<div class="card-body">
<div class="input-group">
<input class="form-control" type="text" placeholder="Enter search term..." aria-label="Enter search term..." aria-describedby="button-search" />
<button class="btn btn-primary" id="button-search" type="button">Go!</button>
</div>
</div>
</div>
<!-- Categories widget-->
<div class="card mb-4">
<div class="card-header">Categories</div>
<div class="card-body">
<div class="row">
<div class="col-sm-6">
<ul class="list-unstyled mb-0">
@foreach($categories as $category)
<li><a href="#!">{{ $category->name }}</a></li>
@endforeach
</ul>
</div>
</div>
</div>
</div>
<!-- Side widget-->
<div class="card mb-4">
<div class="card-header">Side Widget</div>
<div class="card-body">You can put anything you want inside of these side widgets. They are easy to use, and feature the Bootstrap 5 card component!</div>
</div>
</div>
</div>
</div>
@endsection
我们的文章就已经成功渲染了出来。浏览器看看效果吧。
根据分类显示文章
我们已经完成了文章的显示,不过,获取的是所有文章。下面,我们为文章添加一个过滤的功能,按照文章类型进行搜索。
1、修改视图文件
resources/views/home.blade.php
...
<!-- Categories widget-->
<div class="card mb-4">
<div class="card-header">Categories</div>
<div class="card-body">
<div class="row">
<div class="col-sm-6">
<ul class="list-unstyled mb-0">
@foreach($categories as $category)
<li><a href="{{ route('home') }}?category_id={{ $category->id }}">{{ $category->name }}</a></li>
@endforeach
</ul>
</div>
</div>
</div>
</div>
...
2、控制器中进行搜索
app/Http/Controllers/HomeController.php
...
public function index()
{
...
// 获取所有文章
$posts = Post::where('category_id', request('category_id'))->latest()->get();
...
}
...
此时,就已经可以访问了,请先按照下面的顺序进行访问:
-
http://b-laravel11-blog.test/
-
http://b-laravel11-blog.test/?category_id=1
此时,应该会发现问题了,当不传递 category_id
参数时,获取不到数据。
3、默认显示所有文章
由此,我们会想到一个方法,当不传递 category_id
参数时,就默认显示所有文章。在 Laravel 中,我们可以使用 when
方法来实现。
app/Http/Controllers/HomeController.php
...
public function index()
{
...
// 获取所有文章
$posts = Post::when(request('category_id'), function ($query) {
$query->where('category_id', request('category_id'));
})->latest()->get();
...
}
...
使用 when
方法时,当请求中 category_id
存在时,才会去执行 where
条件查询。不存在时就显示所有文章。
请登录后再评论