如何在数据库中存储单选框、复选框、下拉菜单类问卷问题的选项?
解决问卷选项存储的完整方案
嘿,针对你这个需要存储checkbox、单选按钮、下拉菜单类问卷选项的问题,我给你一套从数据库设计到前后端代码修改的完整解决方案:
1. 数据库设计:新增选项表
你需要新建一个question_options表,用来和现有的questions表形成一对多关联(一个问题对应多个选项),表结构如下:
CREATE TABLE question_options ( id INT AUTO_INCREMENT PRIMARY KEY, question_id INT NOT NULL, option_text VARCHAR(255) NOT NULL, sort_order INT DEFAULT 0, -- 控制选项显示顺序,可选但实用 FOREIGN KEY (question_id) REFERENCES questions(id) ON DELETE CASCADE );
ON DELETE CASCADE的作用是:当删除某个问题时,对应的所有选项会自动删除,避免产生无效的垃圾数据。
2. 前端表单修改:让选项能被后端接收
你需要给选项输入框加上name="options[]"属性,这样后端可以接收一个选项数组;同时要确保动态添加的选项也带有这个name,还要完善删除按钮的事件绑定:
修改选项区域的HTML
<div class="form-group" id="availableOptions"> <label for="inputName" class="text-heading h6 font-weight-semi-bold">Available options</label> <div class="option d-flex justify-content-between"> <input type="text" class="form-control col-md-8" name="options[]" required> <button class="removeOption btn btn-outline-primary col-md-3">Remove option</button> </div> <div class="option mt-3 d-flex justify-content-between"> <input type="text" class="form-control col-md-8" name="options[]" required> <button class="removeOption btn btn-outline-primary col-md-3">Remove option</button> </div> </div>
完善jQuery代码
$('#addNewOption').hide(); $('#availableOptions').hide(); $('#customQuestionType').change(function(){ var selected_option = $('option:selected', this).val(); if (selected_option == "select_menu" || selected_option == "radio_btn" || selected_option == "checkbox") { $('#addNewOption').show(); $('#availableOptions').show(); } else { $('#availableOptions').hide(); $('#addNewOption').hide(); } }); // 动态添加选项(确保新输入框带name属性) $('#addNewOption').click(function() { $('#availableOptions').append( '<div class="option form-row mt-3 d-flex justify-content-between">' + '<input type="text" class="form-control col-md-8" name="options[]" required>' + '<button class="removeOption btn btn-outline-primary col-md-3">Remove Option</button>' + '</div>'); }); // 事件委托处理动态添加的删除按钮 $(document).on('click', '.removeOption', function() { $(this).parent('.option').remove(); });
3. 后端代码修改:存储问题与选项
3.1 新建QuestionOption模型
创建app/Models/QuestionOption.php(Laravel 8+版本):
namespace App\Models; use Illuminate\Database\Eloquent\Model; class QuestionOption extends Model { protected $fillable = ['question_id', 'option_text', 'sort_order']; // 关联到问题模型 public function question() { return $this->belongsTo(Question::class); } }
3.2 更新Question模型的关联
在现有Question模型中添加一对多关联:
class Question extends Model { protected $fillable = ['conference_id', 'question', 'type']; public function registration_type(){ return $this->belongsToMany('App\TicketType', 'ticket_type_questions')->withPivot('required'); } // 新增:一个问题对应多个选项 public function options() { return $this->hasMany(QuestionOption::class)->orderBy('sort_order'); } }
3.3 修改QuestionController的store方法
更新验证规则,针对需要选项的问题类型强制校验选项;创建问题后批量存储选项:
public function store(Request $request, $id){ // 基础验证规则 $rules = [ 'question' => 'required|max:255|string', 'type' => 'required|in:text,long_text,checkbox,radio_btn,select_menu', ]; // 需要选项的问题类型 $optionRequiredTypes = ['checkbox', 'radio_btn', 'select_menu']; if(in_array($request->type, $optionRequiredTypes)){ $rules['options'] = 'required|array|min:2'; // 至少2个选项 $rules['options.*'] = 'required|string|max:255'; } $this->validate($request, $rules); $conference = Conference::find($id); $question = Question::create([ 'conference_id' => $conference->id, 'question' => $request->question, 'type' => $request->type, ]); // 批量创建选项 if(in_array($request->type, $optionRequiredTypes)){ $options = collect($request->options)->map(function($text, $index){ return [ 'option_text' => $text, 'sort_order' => $index + 1 // 按输入顺序设置排序 ]; }); $question->options()->createMany($options->toArray()); } Session::flash('success', 'Question created with success.'); return redirect()->back(); }
额外小提示
- 后续做问题编辑功能时,记得要加载现有选项,并在更新时同步选项(删除旧选项、添加新选项或修改内容)
- 可以在前端添加逻辑:当切换到不需要选项的类型时,清空所有选项输入框的内容,避免提交无效数据
内容的提问来源于stack exchange,提问作者johnW
相关产品推荐
相关产品推荐

