You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel项目首页展示每个Category下的最新Post?

如何在首页展示每个分类下的最新文章?

嘿,我来帮你搞定这个需求!先咱们先把基础的模型关联捋顺,然后给你两种实用的实现方式,你可以根据自己的场景选~

第一步:确保模型关联正确

首先,咱们得给Category和Post模型添加上关联方法,这是Laravel Eloquent处理关系的基础:

Category 模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    // 一个分类对应多篇文章
    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    // 定义关联,直接获取该分类的最新文章
    public function latestPost()
    {
        return $this->hasOne(Post::class)->latest();
    }
}

Post 模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    // 一篇文章属于一个分类
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}

方法一:用Eloquent关联预加载(简洁直观)

这种方式最适合大多数场景,代码简洁,可读性强,还能避免N+1查询问题。

控制器代码

在你的首页控制器(比如HomeController)的index方法里,查询所有分类并预加载每个分类的最新文章:

public function index()
{
    $categories = Category::with('latestPost')->get();

    return view('home', compact('categories'));
}

视图代码

在首页视图(比如resources/views/home.blade.php)里循环渲染分类和对应的最新文章:

@foreach($categories as $category)
    <div class="category-card">
        <h3>{{ $category->name }}</h3>
        @if($category->latestPost)
            <div class="latest-post-item">
                <h4>{{ $category->latestPost->title }}</h4>
                <!-- 截断文章内容,显示前100个字符 -->
                <p>{{ \Illuminate\Support\Str::limit($category->latestPost->body, 100) }}</p>
                @if($category->latestPost->image)
                    <!-- 注意:要先执行php artisan storage:link创建存储软链接 -->
                    <img src="{{ asset('storage/' . $category->latestPost->image) }}" 
                         alt="{{ $category->latestPost->title }}"
                         class="post-image">
                @endif
            </div>
        @else
            <p class="empty-tip">该分类还没有发布文章哦~</p>
        @endif
    </div>
@endforeach

方法二:用查询构造器实现(灵活可控)

如果需要更复杂的筛选条件(比如只展示某些分类、排除特定状态的文章),可以用这种方式,直接通过数据库查询获取所有分类的最新文章。

控制器代码

public function index()
{
    // 先获取每个分类下最新文章的ID(按created_at倒序取最新)
    $latestPostIds = Post::selectRaw('MAX(id) as post_id')
        ->groupBy('category_id')
        ->pluck('post_id');

    // 根据ID集合获取对应的文章,并关联分类信息
    $latestPosts = Post::with('category')
        ->whereIn('id', $latestPostIds)
        ->get();

    // 把文章按分类分组,方便视图渲染
    $postsByCategory = $latestPosts->groupBy('category_id');

    return view('home', compact('postsByCategory'));
}

视图代码

@foreach($postsByCategory as $categoryPosts)
    @php $category = $categoryPosts->first()->category @endphp
    <div class="category-card">
        <h3>{{ $category->name }}</h3>
        @foreach($categoryPosts as $post)
            <div class="latest-post-item">
                <h4>{{ $post->title }}</h4>
                <p>{{ \Illuminate\Support\Str::limit($post->body, 100) }}</p>
                @if($post->image)
                    <img src="{{ asset('storage/' . $post->image) }}" 
                         alt="{{ $post->title }}"
                         class="post-image">
                @endif
            </div>
        @endforeach
    </div>
@endforeach

小提示

  • 如果想按updated_at(更新时间)而不是created_at(创建时间)判断“最新”,只需要把latest()改成latest('updated_at')即可。
  • 图片访问问题:如果你的image字段存储的是本地文件路径,记得执行php artisan storage:link命令创建存储目录的软链接,否则前端无法访问图片。

内容的提问来源于stack exchange,提问作者user5565240

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:57:17