Laravel图片评论功能实现咨询:附评论表与图片表结构
实现Laravel图片画廊的评论功能
嘿,你已经迈出了实现评论功能的第一步!我来帮你把这个功能完整落地,一步步来:
1. 完善数据库迁移(补全外键约束)
你的comments表迁移已经有了基础字段,但还需要添加外键约束来确保数据关联的完整性,同时补全photos表的迁移(假设你需要基础的图片字段):
补全/修改comments表迁移
public function up() { Schema::create('comments', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('user_id')->index(); $table->unsignedInteger('photo_id')->index(); $table->text('body'); // 这里不需要指定190长度,text类型默认足够,若要限制可以用string(190) $table->timestamps(); // 添加外键约束,确保关联数据删除时评论同步处理 $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('photo_id')->references('id')->on('photos')->onDelete('cascade'); }); }
补全photos表迁移(示例)
public function up() { Schema::create('photos', function (Blueprint $table) { $table->increments('id'); $table->string('title')->nullable(); $table->string('path'); // 存储图片路径 $table->unsignedInteger('user_id')->nullable()->index(); // 如果图片属于某个用户 $table->timestamps(); // 可选:添加用户外键(如果你的画廊有用户上传功能) if (Schema::hasTable('users')) { $table->foreign('user_id')->references('id')->on('users')->onDelete('set null'); } }); }
执行迁移生效:
php artisan migrate
2. 建立模型关联
在对应的模型里定义关联关系,这样Laravel就能轻松获取图片的评论、评论的作者等数据:
Photo模型(app/Photo.php)
namespace App; use Illuminate\Database\Eloquent\Model; class Photo extends Model { // 允许批量赋值的字段 protected $fillable = ['title', 'path', 'user_id']; // 一张图片对应多条评论,按时间倒序排列 public function comments() { return $this->hasMany(Comment::class)->orderBy('created_at', 'desc'); } // 可选:图片属于某个用户(如果你的画廊有用户上传功能) public function user() { return $this->belongsTo(User::class); } }
Comment模型(app/Comment.php)
namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model { protected $fillable = ['body']; // 评论属于一张图片 public function photo() { return $this->belongsTo(Photo::class); } // 评论属于一个用户 public function user() { return $this->belongsTo(User::class); } }
User模型(app/User.php)
// 添加以下方法,关联用户的所有评论 public function comments() { return $this->hasMany(Comment::class); }
3. 创建评论提交逻辑
先创建CommentController来处理评论的提交:
php artisan make:controller CommentController
然后在控制器里写store方法:
namespace App\Http\Controllers; use App\Comment; use App\Photo; use Illuminate\Http\Request; class CommentController extends Controller { public function __construct() { // 只有登录用户才能评论,未登录会自动跳转到登录页 $this->middleware('auth'); } public function store(Request $request, Photo $photo) { // 验证评论内容,限制长度为190字符 $request->validate([ 'body' => 'required|max:190', ]); // 关联图片创建评论,自动填充当前登录用户ID $photo->comments()->create([ 'body' => $request->body, 'user_id' => auth()->id(), ]); // 回到图片详情页并提示成功 return back()->with('success', '评论发布成功!'); } }
在routes/web.php里添加评论提交路由:
// 提交图片评论的路由 Route::post('/photos/{photo}/comments', 'CommentController@store')->name('photos.comments.store');
4. 在视图中添加评论表单和列表
假设你有图片详情页(比如resources/views/photos/show.blade.php),在页面合适位置添加以下内容:
评论表单
<div class="mt-4"> @auth <form action="{{ route('photos.comments.store', $photo) }}" method="POST"> @csrf <div class="form-group"> <textarea name="body" class="form-control @error('body') is-invalid @enderror" rows="3" placeholder="写下你的评论...">{{ old('body') }}</textarea> @error('body') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> <button type="submit" class="btn btn-primary">发布评论</button> </form> @else <p>请<a href="{{ route('login') }}">登录</a>后发表评论</p> @endauth </div>
评论列表
<div class="mt-5"> <h5>评论 ({{ $photo->comments->count() }})</h5> @foreach($photo->comments as $comment) <div class="card mb-2"> <div class="card-body p-3"> <div class="d-flex justify-content-between align-items-start"> <div> <strong>{{ $comment->user->name }}</strong> <small class="text-muted">{{ $comment->created_at->diffForHumans() }}</small> </div> </div> <p class="mt-2 mb-0">{{ $comment->body }}</p> </div> </div> @empty <p class="text-muted">还没有评论,快来抢沙发吧!</p> @endforeach </div>
最后,优化PhotoController的show方法,预加载评论和作者避免N+1查询:
public function show(Photo $photo) { // 预加载评论及评论作者,提升页面性能 $photo->load('comments.user'); return view('photos.show', compact('photo')); }
这样,你就完整实现了图片画廊的评论功能啦!
内容的提问来源于stack exchange,提问作者Totoro Ghibli
相关产品推荐
相关产品推荐

