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

Laravel Eloquent表关联开发:通知确认与取消按钮功能实现

没问题,咱们一步步来实现这个需求,从创建数据表到关联模型再到视图按钮,都给你安排明白:

完整实现步骤

1. 创建确认记录表的迁移与模型

首先用Artisan命令生成迁移文件,用来创建notice_confirmed_student表:

php artisan make:migration create_notice_confirmed_student_table

打开生成的迁移文件(在database/migrations目录下),编写表结构:

public function up()
{
    Schema::create('notice_confirmed_student', function (Blueprint $table) {
        $table->id();
        $table->foreignId('notice_id')->constrained()->onDelete('cascade'); // 关联通知表,删除通知时同步删除确认记录
        $table->foreignId('student_id')->constrained(); // 关联学生表,你可以根据实际业务调整字段名
        $table->timestamps();
        
        // 加个唯一约束,防止同一学生重复确认同一条通知
        $table->unique(['notice_id', 'student_id']);
    });
}

public function down()
{
    Schema::dropIfExists('notice_confirmed_student');
}

接着生成对应的模型:

php artisan make:model NoticeConfirmedStudent

打开app/Models/NoticeConfirmedStudent.php,配置可填充字段和关联关系:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class NoticeConfirmedStudent extends Model
{
    // 允许批量赋值的字段
    protected $fillable = ['notice_id', 'student_id'];

    // 关联Notice模型(多对一)
    public function notice(): BelongsTo
    {
        return $this->belongsTo(Notice::class);
    }

    // 如果有Student模型,添加关联(可选,根据你的业务)
    public function student(): BelongsTo
    {
        return $this->belongsTo(Student::class);
    }
}

最后运行迁移创建表:

php artisan migrate

2. 配置Notice模型的Eloquent关联

打开现有的app/Models/Notice.php,添加和确认记录的一对多关联,再写个辅助方法方便判断当前用户是否已确认:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Notice extends Model
{
    // 原有的代码(比如$fillable)保持不变
    
    // 关联确认记录(一对多)
    public function confirmedStudents(): HasMany
    {
        return $this->hasMany(NoticeConfirmedStudent::class);
    }

    // 辅助方法:判断指定学生是否已确认该通知
    public function isConfirmedBy($studentId): bool
    {
        return $this->confirmedStudents()->where('student_id', $studentId)->exists();
    }
}

3. 添加路由与控制器处理逻辑

先在routes/web.php里添加两个POST路由,分别处理确认和取消确认的请求:

use App\Http\Controllers\NoticeController;

Route::post('/notices/{notice}/confirm', [NoticeController::class, 'confirm'])->name('notices.confirm');
Route::post('/notices/{notice}/cancel-confirm', [NoticeController::class, 'cancelConfirm'])->name('notices.cancel-confirm');

然后在NoticeController里新增两个方法:

namespace App\Http\Controllers;

use App\Models\Notice;
use App\Models\NoticeConfirmedStudent;
use Illuminate\Http\Request;

class NoticeController extends Controller
{
    // 原有的获取通知列表的方法(比如index)保持不变

    // 处理确认通知请求
    public function confirm(Request $request, Notice $notice)
    {
        // 这里假设当前登录用户是学生,用auth()->id()获取用户ID,你可以根据实际调整
        $studentId = auth()->id();

        // 用firstOrCreate避免重复提交
        NoticeConfirmedStudent::firstOrCreate(
            ['notice_id' => $notice->id, 'student_id' => $studentId]
        );

        return back()->with('success', '已成功确认该通知');
    }

    // 处理取消确认请求
    public function cancelConfirm(Request $request, Notice $notice)
    {
        $studentId = auth()->id();
        // 删除当前用户对该通知的确认记录
        $notice->confirmedStudents()->where('student_id', $studentId)->delete();

        return back()->with('success', '已取消该通知的确认');
    }
}

4. 更新视图,添加确认/取消按钮

在遍历通知的循环里,根据当前用户是否已确认,显示对应的按钮:

@foreach($notices as $notice)
    <div class="notice-container">
        <p>{{ $notice->notice }}</p>
        
        @if($notice->isConfirmedBy(auth()->id()))
            <!-- 已确认时显示取消按钮 -->
            <form action="{{ route('notices.cancel-confirm', $notice) }}" method="POST">
                @csrf
                <button type="submit" class="btn btn-outline-secondary">取消确认</button>
            </form>
        @else
            <!-- 未确认时显示确认按钮 -->
            <form action="{{ route('notices.confirm', $notice) }}" method="POST">
                @csrf
                <button type="submit" class="btn btn-primary">确认</button>
            </form>
        @endif
    </div>
@endforeach

如果想要无刷新的体验,可以改成AJAX提交(用jQuery举例):

@foreach($notices as $notice)
    <div class="notice-container">
        <p>{{ $notice->notice }}</p>
        <div class="action-btn">
            @if($notice->isConfirmedBy(auth()->id()))
                <button class="btn btn-outline-secondary cancel-btn" data-id="{{ $notice->id }}">取消确认</button>
            @else
                <button class="btn btn-primary confirm-btn" data-id="{{ $notice->id }}">确认</button>
            @endif
        </div>
    </div>
@endforeach

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
    // 确认按钮逻辑
    $('.confirm-btn').click(function() {
        let noticeId = $(this).data('id');
        let btn = $(this);
        
        $.post(`/notices/${noticeId}/confirm`, { _token: '{{ csrf_token() }}' }, function() {
            btn.replaceWith(`<button class="btn btn-outline-secondary cancel-btn" data-id="${noticeId}">取消确认</button>`);
            alert('确认成功');
        });
    });

    // 取消确认按钮逻辑
    $('.cancel-btn').click(function() {
        let noticeId = $(this).data('id');
        let btn = $(this);
        
        $.post(`/notices/${noticeId}/cancel-confirm`, { _token: '{{ csrf_token() }}' }, function() {
            btn.replaceWith(`<button class="btn btn-primary confirm-btn" data-id="${noticeId}">确认</button>`);
            alert('已取消确认');
        });
    });
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:15:35