
本文详解如何在 laravel 9 中通过数据库字段 + 模型操作实现“精选文章”功能,包括迁移配置、表单处理、数据创建与查询,助你轻松控制某篇文章是否显示在首页推荐位。
本文详解如何在 laravel 9 中通过数据库字段 + 模型操作实现“精选文章”功能,包括迁移配置、表单处理、数据创建与查询,助你轻松控制某篇文章是否显示在首页推荐位。
在 Laravel 9 中实现“Featured Post”(精选/置顶文章)功能,核心思路是为 posts 表添加一个布尔型标识字段(如 featured),并通过该字段的值(0 或 1)动态筛选和展示内容。下面将从数据库、控制器、模型到前端调用完整串联这一流程。
✅ 一、数据库迁移:定义 featured 字段
确保你的迁移文件中正确定义了 featured 字段类型为 tinyInteger(Laravel 推荐用于布尔语义的整数字段),并设置默认值为 0:
// database/migrations/xxxx_xx_xx_create_posts_table.php
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('sub_title')->nullable();
$table->text('tags');
$table->longText('content');
$table->tinyInteger('featured')->default(0); // 关键:默认非精选
$table->timestamps();
});执行迁移后,所有新插入的文章默认 featured = 0(普通文章)。
⚠️ 注意:若已存在数据表,请使用 php artisan make:migration add_featured_to_posts_table 新建迁移,并在其中使用 table->tinyInteger('featured')->default(0)->after('content') 添加字段,再运行 php artisan migrate。
✅ 二、表单与控制器:支持「设为精选」提交
当前 store() 方法中 'featured' => 'nullable' 仅允许空值,但我们需要接收用户勾选(如复选框)传来的 1。建议改为显式判断,并安全转换为整型:
// app/Http/Controllers/PostsController.php
public function store(Request $request)
{
$formFields = $request->validate([
'title' => 'required|string|max:255',
'sub_title' => 'nullable|string',
'tags' => 'required|string',
'content' => 'required|string',
// 移除 'featured' 的 validation 规则,改由逻辑控制
]);
// 若表单提交了 'featured'(如 checkbox 被勾选),则设为 1;否则为 0
$formFields['featured'] = $request->has('featured') ? 1 : 0;
Posts::create($formFields);
return redirect('/')->with('success', '文章发布成功!');
}对应地,在创建文章的 Blade 表单中加入复选框:
<!-- resources/views/posts/create.blade.php -->
<div class="mb-4">
<label class="inline-flex items-center">
<input type="checkbox" name="featured" value="1" class="rounded border-gray-300">
<span class="ml-2">设为精选文章</span>
</label>
</div>✅ 三、模型与查询:高效获取精选文章
在视图中展示精选文章时,切勿使用 @foreach($posts as $post) 全量遍历后判断 if($post->featured) —— 这会拉取全部数据,性能低下。应直接在查询层过滤:
// 在控制器中(如 HomeController@index)
public function index()
{
$featuredPosts = Posts::where('featured', 1)
->latest()
->take(3) // 例如只取前3篇精选
->get();
$allPosts = Posts::latest()->paginate(10);
return view('home', compact('featuredPosts', 'allPosts'));
}在 Blade 模板中调用:
<!-- 首页精选区 -->
@if($featuredPosts->isNotEmpty())
<section class="featured-section">
<h2>精选文章</h2>
@foreach($featuredPosts as $post)
<article>
<h3>{{ $post->title }}</h3>
<p>{{ Str::limit($post->content, 100) }}</p>
</article>
@endforeach
</section>
@endif✅ 四、进阶建议(可选)
- 后台开关优化:在编辑页面提供「切换精选状态」按钮,配合 update() 方法更新 featured 字段;
- Eloquent 访问器:在 Post 模型中添加 getIsFeaturedAttribute(),使 $post->is_featured 返回布尔值,提升可读性;
- 索引优化:对 featured 字段添加数据库索引($table->index('featured')),加速 WHERE featured = 1 查询。
至此,你已具备完整的 Laravel 9 精选文章能力:从数据定义、用户交互、服务端处理到高效渲染,每一步都清晰可控。记住关键原则:用查询过滤代替 PHP 过滤,用整型字段代替字符串标记,用迁移保障结构一致性。


















