You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby报错undefined method `map' for String的排查与解决

问题描述

在ManageIQ自动化脚本开发过程中,尝试将字符串形式的ID列表转换为整数数组时触发报错,核心报错信息为:
NoMethodError: undefined method 'map' for "[\"118\", \"119\"]":String

原始实现代码:

def job_template_by_id
  job_template_id = var_search(@handle.object, 'job_template_id') ||
                    var_search(@handle.object, 'dialog_job_template_id')
               
  job_template_id = job_template_id.map(&:to_i)

  @handle.vmdb(SCRIPT_CLASS).where(:id => job_template_id) if job_template_id
end

完整报错日志:

[----] E, [2022-07-07T16:08:09.928258 #534:2afb827cdb68] ERROR -- automation: Q-task_id([r837_miq_provision_2172]) <AEMethod launch_ansible_job> The following error occurred during method evaluation:
[----] E, [2022-07-07T16:08:09.930286 #534:2afb827cdb68] ERROR -- automation: Q-task_id([r837_miq_provision_2172]) <AEMethod launch_ansible_job>   NoMethodError: undefined method `map' for "[\"118\", \"119\"]":String
[----] E, [2022-07-07T16:08:09.931630 #534:2afb827cdb68] ERROR -- automation: Q-task_id([r837_miq_provision_2172]) <AEMethod launch_ansible_job>   /ManageIQ_Custom/AutomationManagement/AnsibleTower/Operations/StateMachines/Job/launch_ansible_job:113:in `job_template_by_id'
问题根因

调用map方法时,操作对象是内容为数组格式的JSON字符串,而非真正的Array类型实例。Ruby的String类没有实现map方法,因此触发NoMethodError。
这类问题在ManageIQ对话框参数传递场景十分常见:多选控件返回的数组值在部分版本、部分传参链路中会被序列化为JSON字符串,不会自动转成Ruby数组对象。

修复方案

修复逻辑需要兼容三类常见的传参格式:JSON格式的数组字符串、原生Ruby数组、单个ID值,解析完成后再统一做类型转换和无效值过滤。
修复后的代码如下:

require 'json'

def job_template_by_id
  job_template_id = var_search(@handle.object, 'job_template_id') ||
                    var_search(@handle.object, 'dialog_job_template_id')

  return nil unless job_template_id

  # 按实际值类型做格式转换
  job_template_id = case job_template_id
                    when String
                      parsed_val = JSON.parse(job_template_id)
                      parsed_val.is_a?(Array) ? parsed_val : [parsed_val]
                    when Array
                      job_template_id
                    else
                      # 兼容单个ID传参的场景
                      [job_template_id]
                    end

  # 统一转整数,过滤转换失败产生的无效0值
  job_template_id = job_template_id.map(&:to_i).reject(&:zero?)

  @handle.vmdb(SCRIPT_CLASS).where(:id => job_template_id) if job_template_id.any?
end

额外注意事项

  • 可根据实际场景增加JSON解析的异常捕获,避免非法格式的传参直接中断整个自动化流程
  • 增加无效值过滤逻辑后,不会因为空值、非数字值传入生成无效的SQL查询条件
  • 上述写法可以覆盖ManageIQ不同版本对话框参数返回格式不一致的问题,无需针对特定版本做单独适配

内容的提问来源于stack exchange,提问作者user630702

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:09:26