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

如何构建表单实现Event与Question多对多关联数据录入?

实现Event与Question多对多关联的着陆页及事件管理功能

需求概述

开发着陆页展示events表中的各类事件;点击事件后显示详情及关联questions表的问题表单;同时需要创建支持关联问题的事件创建表单,确保多对多关系数据正确关联与展示。


1. 模型关联定义

根据你的表结构,在模型中明确多对多关联关系:

Event 模型

namespace App\Models;

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

class Event extends Model
{
    protected $fillable = ['title', 'description', 'date']; // 按实际表字段补充

    // 与Question的多对多关联
    public function questions(): BelongsToMany
    {
        return $this->belongsToMany(Question::class, 'event_question', 'event_id', 'question_id');
    }
}

Question 模型

namespace App\Models;

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

class Question extends Model
{
    protected $fillable = ['text', 'type']; // 按实际表字段补充

    // 与Event的多对多关联
    public function events(): BelongsToMany
    {
        return $this->belongsToMany(Event::class, 'event_question', 'question_id', 'event_id');
    }
}

2. 数据库表结构

events表

字段名类型说明
idint(主键)事件唯一ID
titlevarchar事件标题
descriptiontext事件描述
datedate事件日期
created_attimestamp创建时间
updated_attimestamp更新时间

questions表

字段名类型说明
idint(主键)问题唯一ID
texttext问题内容
typevarchar问题类型(如单选/文本)
created_attimestamp创建时间
updated_attimestamp更新时间

event_question中间表

字段名类型说明
event_idint关联事件ID
question_idint关联问题ID

3. 控制器逻辑实现

完善控制器的事件列表、详情展示、事件创建与保存功能:

namespace App\Http\Controllers;

use App\Models\Event;
use App\Models\Question;
use Illuminate\Http\Request;

class EventController extends Controller
{
    // 着陆页:按日期展示所有事件
    public function index()
    {
        $events = Event::orderBy('date', 'asc')->get();
        return view('events.index', compact('events'));
    }

    // 事件详情页:加载关联问题
    public function show(Event $event)
    {
        // 预加载关联问题,避免N+1查询
        $event->load('questions');
        return view('events.show', compact('event'));
    }

    // 展示事件创建表单
    public function create()
    {
        $questions = Question::all();
        return view('events.create', compact('questions'));
    }

    // 保存事件及关联问题
    public function store(Request $request)
    {
        // 验证表单数据
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'description' => 'nullable|text',
            'date' => 'required|date',
            'question_ids' => 'nullable|array',
            'question_ids.*' => 'exists:questions,id'
        ]);

        // 创建事件
        $event = Event::create($validated);

        // 关联选中的问题
        if ($request->has('question_ids')) {
            $event->questions()->attach($request->question_ids);
        }

        return redirect()->route('events.index')->with('success', '事件创建成功');
    }
}

4. 视图实现

着陆页视图(resources/views/events/index.blade.php)

<h1>活动列表</h1>
<div class="events-container">
    @foreach($events as $event)
        <div class="event-card">
            <h3>{{ $event->title }}</h3>
            <p>{{ $event->description }}</p>
            <p>举办日期:{{ $event->date->format('Y-m-d') }}</p>
            <a href="{{ route('events.show', $event) }}" class="btn">查看详情</a>
        </div>
    @endforeach
</div>
<a href="{{ route('events.create') }}" class="btn btn-primary">创建新活动</a>

事件创建表单视图(resources/views/events/create.blade.php)

<h1>创建新活动</h1>
<form method="POST" action="{{ route('events.store') }}">
    @csrf
    <div class="form-group">
        <label for="title">活动标题</label>
        <input type="text" id="title" name="title" value="{{ old('title') }}" required>
        @error('title')
            <span class="text-red-500">{{ $message }}</span>
        @enderror
    </div>

    <div class="form-group">
        <label for="description">活动描述</label>
        <textarea id="description" name="description">{{ old('description') }}</textarea>
    </div>

    <div class="form-group">
        <label for="date">举办日期</label>
        <input type="date" id="date" name="date" value="{{ old('date') }}" required>
        @error('date')
            <span class="text-red-500">{{ $message }}</span>
        @enderror
    </div>

    <div class="form-group">
        <label>关联问题</label>
        @foreach($questions as $question)
            <div class="checkbox-item">
                <input type="checkbox" id="question-{{ $question->id }}" name="question_ids[]" value="{{ $question->id }}" {{ in_array($question->id, old('question_ids', [])) ? 'checked' : '' }}>
                <label for="question-{{ $question->id }}">{{ $question->text }}</label>
            </div>
        @endforeach
    </div>

    <button type="submit" class="btn btn-primary">创建活动</button>
</form>

事件详情页视图(resources/views/events/show.blade.php)

<h1>{{ $event->title }}</h1>
<p>{{ $event->description }}</p>
<p>举办日期:{{ $event->date->format('Y-m-d') }}</p>

<h2>活动问卷</h2>
<form method="POST" action="{{ route('responses.store') }}"> <!-- 可根据需求调整提交路由 -->
    @csrf
    <input type="hidden" name="event_id" value="{{ $event->id }}">
    @foreach($event->questions as $question)
        <div class="question-group">
            <p>{{ $question->text }}</p>
            <!-- 根据问题类型渲染对应输入组件,示例为文本框 -->
            <input type="text" name="responses[{{ $question->id }}]" placeholder="请输入回答">
        </div>
    @endforeach
    <button type="submit" class="btn btn-primary">提交问卷</button>
</form>

<a href="{{ route('events.index') }}" class="btn">返回活动列表</a>

5. 路由配置

在routes/web.php中添加路由:

use App\Http\Controllers\EventController;

Route::get('/events', [EventController::class, 'index'])->name('events.index');
Route::get('/events/{event}', [EventController::class, 'show'])->name('events.show');
Route::get('/events/create', [EventController::class, 'create'])->name('events.create');
Route::post('/events', [EventController::class, 'store'])->name('events.store');

内容的提问来源于stack exchange,提问作者melissa maria pleitez ramirez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:18:08