RoR开发实现李克特量表问卷表单及结果反馈功能求助
RoR 李克特量表问卷系统实现方案
一、数据模型与关联设计
首先修正核心设计错误:李克特量表为多档有序选项,不能用boolean类型存储答题响应,boolean仅支持true/false两态,无法匹配多选项场景;同时必须单独拆分Question模型,不要将题面硬编码在视图或配置中,后续调整题目、分类无需修改业务代码。
具体模型设计参考:
- 在
User模型新增user_type字段,用integer枚举存储三类用户身份:0: 激励型、1: 变革型、2: 关系型,加校验限制字段值合法。 Question模型字段配置:content:string存储题面文本user_type:integer枚举值,标记题目对应作答的用户类型,渲染表单时直接按当前用户类型拉取对应题组即可position:integer存储题目排序值,控制表单展示顺序
Response模型字段配置:answer:integer用枚举整数存储用户选项,不要用string类型,避免大小写、拼写差异导致统计误差,映射规则参考:0: Nunca(从不)、1: Rara vez(很少)、2: A veces(有时)、3: Casi siempre(几乎总是)、4: Siempre(总是)- 外键字段:
user_id:bigint关联作答用户,question_id:bigint关联对应题目 - 加数据库唯一索引:
add_index :responses, [:user_id, :question_id], unique: true,避免同一用户对同一道题重复提交多条记录
模型关联配置:
# app/models/user.rb has_many :responses, dependent: :destroy # app/models/question.rb has_many :responses, dependent: :destroy # app/models/response.rb belongs_to :user belongs_to :question validates :answer, presence: true, inclusion: { in: 0..4 } validates :question_id, uniqueness: { scope: :user_id }
表单渲染时直接为radio按钮绑定对应选项的整数值,提交参数类型和数据库字段类型一致,配合关联即可正常保存数据,不会出现之前类型不匹配、关联缺失导致的保存失败问题。
二、答题统计与反馈逻辑实现
统计逻辑不要写在控制器或视图中,抽成独立Service对象封装,方便后续调整规则、复用代码:
- 新建服务类
app/services/feedback_calculator.rb,核心逻辑为拉取用户对应类型的所有有效答题记录,计算各选项占比后按规则匹配反馈文案:
class FeedbackCalculator OPTION_MAP = { never: 0, rarely: 1, sometimes: 2, almost_always: 3, always: 4 }.freeze def initialize(user) @user = user # 仅拉取当前用户所属类型对应的答题记录,避免跨类型题目干扰统计结果 @responses = @user.responses.joins(:question).where(questions: { user_type: @user.user_type }) @total = @responses.count.to_f end def call return "请完成所有题目后查看反馈" if @total.zero? always_ratio = @responses.where(answer: OPTION_MAP[:always]).count / @total almost_always_ratio = @responses.where(answer: OPTION_MAP[:almost_always]).count / @total # 按优先级匹配规则,避免多规则同时命中时返回混乱 if always_ratio > 0.5 "对应「总是」选项占比超50%的反馈文案" elsif almost_always_ratio >= 0.6 "对应「几乎总是」选项占比达60%的反馈文案" else "其他场景默认反馈文案" end end end
- 控制器中表单校验通过、数据保存成功后,直接调用服务获取反馈,传给结果页渲染即可:
def submit # 省略表单参数校验、答题保存逻辑 @feedback = FeedbackCalculator.new(current_user).call end
注意事项
- 反馈阈值、文案如果需要频繁调整,不要硬编码在服务类中,可以抽离到单独的YAML配置文件或数据库配置表,调整时无需修改业务代码
- 统计前必须校验用户已完成对应类型的所有必答题,否则占比计算结果会失真
- 选项和整数的映射关系确定后不要随意修改,否则会导致历史答题数据匹配错乱
内容的提问来源于stack exchange,提问作者pargara
相关产品推荐
相关产品推荐

