Rails 5加载CSV转JSON时出现No such file or directory错误
解决Rails中读取Asset目录下CSV文件并转JSON的问题
你遇到的核心问题是混淆了前端访问的Asset URL路径和本地文件系统路径:asset_path生成的是浏览器能访问的带哈希的URL,并不是本地文件的实际物理路径,所以直接用File.read去读这个路径自然会找不到文件。下面给你两种可行的解决方案:
方案一:直接读取原始文件路径
既然你明确知道CSV文件的位置是app/assets/csvs/nodes.csv,直接用Rails.root.join构造本地文件路径即可,完全绕开asset_path的哈希问题:
require 'csv' require 'json' # 构造本地文件的绝对路径 csv_path = Rails.root.join('app', 'assets', 'csvs', 'nodes.csv') csv_data = File.read(csv_path) @data = CSV.parse(csv_data).to_json
这种方法简单直接,适合你明确知道文件位置的场景,开发和生产环境都能正常工作(只要部署时包含这个原始文件)。
方案二:通过Sprockets查找Asset内容
如果想利用Rails的Asset Pipeline查找机制(比如文件可能放在多个asset目录下),可以用Rails.application.assets.find_asset获取asset对象,直接读取它的内容,不需要关心物理路径:
require 'csv' require 'json' # 查找asset对象 asset = Rails.application.assets.find_asset('nodes.csv') if asset.present? # 直接获取文件内容 csv_data = asset.to_s @data = CSV.parse(csv_data).to_json else # 处理文件不存在的情况,返回空数组JSON @data = '[]' end
为什么原来的方法会报错?
ActionController::Base.helpers.asset_path('nodes.csv')返回的是前端访问用的URL(比如/assets/nodes-0ae0ea4856...csv),这个路径对应的物理文件在:
- 开发环境下:Sprockets是动态编译的,这个文件不会实际生成在
public/assets目录里,本地自然找不到 - 生产环境下:预编译后文件会出现在
public/assets目录,但你需要拼接Rails.root.join('public')才能正确读取,显然不如直接读原始文件方便
内容的提问来源于stack exchange,提问作者brianrhea
相关产品推荐
相关产品推荐

