Rails 4.2.6验证仅控制台生效,控制器(浏览器请求)无效
嘿,我之前也碰到过一模一样的问题!控制台里验证跑起来好好的,一到浏览器通过控制器处理就失效,大概率是控制器的操作绕开了验证,或者参数处理出了问题。咱们一步步来排查:
1. 检查控制器是否跳过了验证
先去看处理InquiryInteger的控制器(比如InquiriesController)里的创建/更新动作,有没有用这类写法:
@inquiry.save(validate: false) # 或者 @inquiry.update_attributes(validate: false)
这种带validate: false的调用会直接绕过所有模型验证——控制台里你用的是普通的save(),所以验证生效,但控制器里这么写就会直接跳过。解决方法很简单:把validate: false去掉,用标准的save、update或者create方法就行。
2. 确认强参数(Strong Parameters)包含了answer字段
Rails的强参数机制会过滤掉没明确允许的参数,如果你的参数白名单里没加answer,那浏览器提交的answer值根本不会被赋值到模型实例上,验证自然不会触发。
检查控制器里的参数方法,应该像这样:
def inquiry_integer_params params.require(:inquiry_integer).permit(:answer, :question_id, :session_id) # 确保answer在允许列表里 end
可以临时在控制器里加一行日志输出,看看提交的参数有没有answer:
logger.debug "Received params: #{inquiry_integer_params.inspect}"
然后看服务器日志,如果输出里没有answer,那就是强参数的问题,把它加到permit里就行。
3. 排查父模型Inquiry的影响
你的InquiryInteger继承自Inquiry,父模型可能有一些回调或者验证逻辑干扰了子模型:
- 检查父模型有没有
before_save、around_save这类回调,会不会修改answer的值,或者跳过验证? - 父模型有没有定义同名的验证,覆盖了子模型的
numericality验证?
可以临时注释掉父模型的一些回调/验证,测试下验证是否恢复正常,来定位问题。
4. 检查参数的类型与赋值情况
浏览器提交的参数默认都是字符串类型,虽然numericality验证会检查值是否可以转换为整数,但如果参数没正确赋值到模型上,也会导致验证不触发。可以在控制器里加一行代码,打印模型实例的answer值和类型:
@inquiry = InquiryInteger.new(inquiry_integer_params) logger.debug "Answer value: #{@inquiry.answer}, type: #{@inquiry.answer.class}"
如果输出里answer是nil或者空字符串,那说明参数没传对,或者强参数没放行,回到第二步排查。
按照这几个步骤排查,应该能很快找到问题所在!
内容的提问来源于stack exchange,提问作者Phipsen

