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

Rails升级后CustomGoogleDirections调用出现Errno::ENOENT错误排查

问题

我定义了继承自GoogleDirections的CustomGoogleDirections类,设置了Google Directions API的XML接口地址。在控制器中调用该类,传入地点参数计算路线英里距离与分钟级驾驶时间,Rails版本升级后出现Errno::ENOENT错误(提示文件或目录不存在)。直接访问生成的API链接可正常获取经纬度等信息,请问问题出在哪里?

相关代码如下:

class CustomGoogleDirections < GoogleDirections
  @@base_url = "https://maps.googleapis.com/maps/api/directions/xml"
end

控制器调用代码:

@locations = @all_locations.each_cons(2).with_index.with_object({}) do |((e1, e2), i), h|
  h[i + 1] = 
    [e1, e2,
     CustomGoogleDirections.new(e1, e2, key: Figaro.env.google_translate_secret_key).distance_in_miles, CustomGoogleDirections.new(e1, e2, key: Figaro.env.google_translate_secret_key).drive_time_in_minutes.url]
end

错误信息:

Errno::ENOENT (No such file or directory @ rb_sysopen - https://maps.googleapis.com/maps/api/directions/xml?destination=60%2BBarron%2BRoad%252C%2BDubai%252C%2BDubai&key=######################&origin=60%2BAlFhaged%2BRoad%252C%2BDubai%252C%2Dubai)
问题原因与修复

原因

这个错误的核心是:Ruby/Rails版本升级后,open-uri的默认行为发生了变化,或者GoogleDirections gem内部使用了File.open这类本地文件操作方法来请求远程HTTPS URL,而新版本的Ruby不再允许这种直接把远程URL当作本地文件处理的操作,导致系统误以为要打开本地目录下的文件,从而抛出“文件或目录不存在”的错误。

修复方案

  1. 检查并升级GoogleDirections gem
    先确认该gem是否有适配新版本Ruby/Rails的更新,直接升级gem版本是最简单的解决方案。如果gem已经停止维护,则需要手动修改请求逻辑。

  2. 重写自定义类的请求逻辑
    在CustomGoogleDirections类中替换底层的请求方式,使用标准的HTTP客户端(比如Net::HTTP)来获取API响应,替代原来依赖open-uri的逻辑:

    class CustomGoogleDirections < GoogleDirections
      @@base_url = "https://maps.googleapis.com/maps/api/directions/xml"
    
      # 重写gem中获取响应的方法,改用Net::HTTP请求
      def fetch_response
        uri = URI.parse(build_url)
        response = Net::HTTP.get_response(uri)
        raise "API请求失败: #{response.message}" unless response.is_a?(Net::HTTPSuccess)
        response.body
      end
    
      # 替换gem中原有的解析响应方法,使用新的fetch_response
      def parse_response
        @response ||= Nokogiri::XML(fetch_response)
      end
    end
    

    注:具体需要重写的方法名可能需要参考GoogleDirections gem的源码,确保覆盖原来使用open-uri的逻辑。

  3. 优化控制器代码(额外建议)
    控制器中重复实例化CustomGoogleDirections会导致重复请求API,既浪费资源又降低性能,建议修改为只实例化一次:

    @locations = @all_locations.each_cons(2).with_index.with_object({}) do |((e1, e2), i), h|
      directions = CustomGoogleDirections.new(e1, e2, key: Figaro.env.google_translate_secret_key)
      h[i + 1] = [e1, e2, directions.distance_in_miles, directions.drive_time_in_minutes.url]
    end
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:35:23