ruby-on-rails - Rails ActiveStorage 问题:rails_blob_path 的“找不到文件”错误,即使路径手动工作
问题描述
我有一个在本地运行良好的小型 Rails 应用程序,使用 ActiveStorage 上传 docx 文件并将其转换为 html(以及其他内容)。要将其部署到 Heroku,我需要从使用本地文件系统进行存储更改为使用 S3,从而更改生成文件路径的方式。
我的研究表明rails_blob_path
(或_url
)应该是我需要的,但我收到“找不到文件”错误,即使文件路径在我手动尝试时有效。
如何为可用于进一步转换的附件生成路径?文档说这很简单,但我无法让它工作!
我的应用程序有项目,每个项目都必须通过 ActiveStorage 附加一个文件。创建项目后(及其附件),文件被处理并将其内容显示给用户(从 Word 文件中提取文本,将其与单词列表进行匹配并存储生成的 HTML 和单词列表以供进一步使用由用户编辑)。
我最初的方法是在项目模型中使用这种方法:
def real_file_path
ActiveStorage::Blob.service.send(:path_for, file.key)
end
然后,在控制器中,我调用了这个方法来进行实际的转换:
def convert_docx_file
_file_contents = ''
_doc = Docx::Document.open(@project.real_file_path)
_doc.paragraphs.each do |p|
_file_contents += p.to_html
end
@project.update_attributes(file_contents: _file_contents)
end
(这使用 DOCX gem 创建一个合适的对象,然后对其进行迭代并将段落转换为 HTML。)
现在有问题的步骤是创建 _doc 对象。上面的代码在本地文件系统上运行良好。对于 S3 的使用,经过大量的研究和实验,我将其更改为:
.
.
_doc = Docx::Document.open(rails_blob_path(@project.file))
.
.
.
在我的本地机器上运行时,这会产生错误:Zip::Error in ProjectsController#show
File /rails/active_storage/blobs/BLAH_BLAH_BLAH/original%20file.docx not found
. 但是,当我将地址复制并粘贴到浏览器中时,它可以正常下载。
谁能让我知道如何获得正确的文件路径,以便我可以再次进行转换?
解决方案
所以,最后,我通过在服务类中创建一个下载器来回避这个问题,我将把这些细节留给可能有同样问题的其他人。
控制器中的相关行现在是:
_doc = DocxDownloadService.new(@project.file).doc
服务类 ( app/services/docx_download_service.rb
) 或多或少直接来自 ActiveStorage 文档:
class DocxDownloadService
include ActiveStorage::Downloading
attr_reader :blob
def initialize(blob)
@blob = blob
end
def doc
download_blob_to_tempfile do |file|
Docx::Document.open(file)
end
end
end
这在本地(在我的文件系统上)和使用 S3 的服务器上都有效。
推荐阅读
- flutter - Flutter:如何返回到特定的底部导航栏
- python - 如何计算图像的对比度?
- sql - 如何获得当前周的前一周?
- java - 查找数组的索引,然后根据该索引查找值
- typescript - 将 const 变量传递给 TypeScript 中的函数
- sql - Jasper 查询 (oracle) 不支持的 SQL92 令牌
- html - HTML 调用 .msg
- kubernetes - 如何制作 Kubernetes 集群的本地(开发人员)副本
- laravel - Laravel 6.x - 缓存'分页()'
- angular - 链接一个守卫(canDeactivate)和一个不使用RouterModule的组件