RoR报undefined method `key?' for "/login"错误原因及修复方法
错误原因
报错undefined method 'key?' for "/login"的触发逻辑非常明确:Rails的表单辅助方法simple_form_for约定,html:参数后必须传入哈希类型的键值对,用来配置表单的class、id、自定义属性等HTML特性。你在代码里直接把返回字符串"/login"的路由方法loginuser_path传给了html:参数,Rails渲染表单时会尝试对html:传入的对象调用key?方法校验配置项,字符串类型没有实现这个方法,直接抛出异常。
修复方案
- 修正表单传参格式:表单提交地址不属于html配置项,要单独传给
url:参数,原错误代码行:
替换为正确写法:<%= simple_form_for @contact, html: loginuser_path do |f| %>
如果是RESTful规范的资源表单,simple_form会自动根据<%= simple_form_for @contact, url: loginuser_path, method: :post do |f| %>@contact是否为新记录匹配对应提交路由,不需要手动指定url;这里是自定义二次校验逻辑的非标准表单,手动指定url即可 - 修正控制器中的语法错误:Ruby的空值常量为小写
nil,大写NIL属于未初始化常量,会触发额外报错。原home动作里的判断逻辑修改为:def home if current_user.nil? redirect_to new_user_session_path else @client = Client.find_by(user_id: current_user.id) @contact = Contact.find_by(client_id: @client.id) redirect_to loginuser_path end end - 补全控制器空值容错:如果当前登录用户未关联Client或Contact记录,
find_by会返回nil,后续调用关联属性会触发空指针错误,建议给loginuser动作增加拦截逻辑:def loginuser @client = Client.find_by(user_id: current_user.id) return redirect_to root_path, alert: "无系统访问权限" unless @client @contact = Contact.find_by(client_id: @client.id) @contact ||= Contact.new end
风险提示
当前代码中使用Contact模型的pass字段明文存储校验密码存在严重安全隐患,建议对校验密码做加盐哈希处理后存储,禁止明文留存敏感身份信息。
内容的提问来源于stack exchange,提问作者Juan Pablo Grover Pinto
相关产品推荐
相关产品推荐

