提交表单后Rails控制器中params为nil的问题求助
params居然是nil? 我用jQuery提交下面这个表单:
<form data-type="html" novalidate="novalidate" id="free_circuit_form" class="new_experiment" action="/en/experiments" accept-charset="UTF-8" method="post"> <input name="utf8" type="hidden" value="✓" /> <input type="hidden" name="authenticity_token" value="+0BPI4JbryN/WVCGrA0OxZNIteXb0p01XZJsxVtW9qYFIxt0EgQ6OJ2rDpaTmQwlVPe9a/qlwEteHvnjWbysOw==" /> <input type="hidden" id="experiment_not_signed_in_circuit_data" name="experiment[not_signed_in_circuit_data]"/> </form>
但在控制器里访问params的时候居然拿到的是nil!按说params应该包含所有提交的参数才对呀?
我在Experiment控制器里是这么配置参数强允许的:
def experiment_params params.require(:experiment).permit( : not_signed_in_circuit_data, :title, :circuit, :intro_text, :public, :meta_description, :thumbnail => [:data], :descriptions_attributes => [:id, :data, :title, :position], :circuits_attributes => [:id, :data, :title, :position, :circuit_types] ) end
编辑补充:
后来我把处理动作移到ApplicationController里了,服务器日志明明显示参数已经传过来了:
Started POST "/en/not_signed_in_circuit" for 127.0.0.1 at 2018-05-12 18:38:24 +0300 Processing by ApplicationController#not_signed_in_circuit as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"tNwIjklA9Ic3u7jOpMJUSPPd8lDmKkZTppG0UvQuBchKv1zZ2R9hnNVJ5t6bVlaoNGL63sddGy2lHSF09sRfVQ==", "experiment"=>{"not_signed_in_circuit_data"=>"{\"public\":false,\"title\":\"abc\",\"circuits\":[{\"circuit\":\"0\",\"text\":\"\"}]}"}, "locale"=>"en"}
可动作里的params还是nil,这到底咋回事啊?
我帮你梳理几个大概率的问题点,你可以挨个排查:
先检查控制器里有没有误写覆盖
params的代码
说出来可能有点离谱,但有时候手滑或者复制粘贴时,会不小心写出params = nil或者params = some_variable这种代码,直接把Rails提供的params对象给覆盖了。你仔细看看处理这个请求的控制器动作,有没有这类操作,有的话删掉就行。排查自定义中间件或特殊gem的影响
如果你的项目里加了自定义Rack中间件,或者用了一些比较小众的gem,有可能中间件在请求到达控制器之前就把params给清空或者篡改了。你可以先临时注释掉非核心的中间件,看看问题会不会消失,逐步定位是哪个组件搞的鬼。确认jQuery的提交方式是否正确
你是用表单自带的submit()方法提交,还是手动用$.ajax发送请求?如果是手动写$.ajax,一定要确保正确序列化表单数据,比如用$('#free_circuit_form').serialize()作为data参数,而且别乱改contentType——表单提交默认用application/x-www-form-urlencoded就好,除非你特意要传JSON,不然改成其他类型可能导致Rails解析失败。先修正参数强允许里的语法错误
你在experiment_params里的: not_signed_in_circuit_data前面多了个空格!这个空格会让Rails识别参数名出错,应该改成:not_signed_in_circuit_data。虽然这个问题不会让全局params变成nil,但会导致你用experiment_params拿不到对应参数,先修正避免后续混淆。打印原始请求体排查解析问题
如果上面的都没问题,你可以在控制器动作里加一行puts request.raw_post,看看实际收到的请求体内容。如果request.raw_post能看到正确的表单数据,但params还是nil,那大概率是Rails的参数解析出了问题,可能和请求的content-type或者中间件的配置有关。
内容的提问来源于stack exchange,提问作者simo

