使用combine_pdf gem合并PDF后,如何将文件存储到@s相关对象?
如何将CombinePDF合并后的PDF存储到ActiveRecord对象中?
看起来你已经把CombinePDF的合并逻辑跑通了,很棒!要把合并后的PDF存到你的@s相关对象(应该是Rails的ActiveRecord模型吧?)里,最常用的方式是借助Rails自带的Active Storage,或者你项目里用的文件上传gem(比如CarrierWave)。下面给你具体的实现步骤:
前提准备(使用Active Storage)
如果你的项目还没配置Active Storage,先跑一下初始化命令:
rails active_storage:install rails db:migrate
然后在你的目标模型(比如Task,对应你的@task对象)里添加附件关联:
class Task < ApplicationRecord # 如果你只需要存一个合并后的PDF,用has_one_attached has_one_attached :combined_pdf # 如果需要存多个,就用has_many_attached :combined_pdfs end
具体实现代码
在你完成PDF合并后,直接把合并后的二进制内容附加到模型的附件字段即可:
# 你的原有合并逻辑 pdf = CombinePDF.new pdf << CombinePDF.parse(Net::HTTP.get_response(URI.parse(@task.assignable.pdf_file.try(:file).try(:url))).body, allow_optional_content: true) pdf << CombinePDF.load(file1_path) # 把合并后的PDF二进制内容包装成IO对象(Active Storage需要IO类型的输入) pdf_io = StringIO.new(pdf.to_pdf) # 设置path属性是为了让Active Storage正确识别文件类型(可选,但推荐) pdf_io.path = "combined.pdf" # 将PDF附加到@task对象的combined_pdf字段 @task.combined_pdf.attach( io: pdf_io, filename: "combined.pdf", content_type: "application/pdf" ) # 记得保存对象(如果@task还没持久化到数据库的话) @task.save!
如果你用的是CarrierWave等其他文件上传gem
如果你的项目用的是CarrierWave这类上传器,逻辑类似,把二进制内容写入模型的文件字段即可:
# 原有合并逻辑不变 pdf = CombinePDF.new # ... 合并步骤 ... # 将二进制内容转为StringIO,赋值给模型的上传器字段 @task.combined_pdf = StringIO.new(pdf.to_pdf) # 手动设置内容类型(有些上传器需要) @task.combined_pdf.file.instance_write(:content_type, "application/pdf") # 保存对象 @task.save!
一些注意事项
- 建议给网络请求的部分加异常处理,比如
Net::HTTP.get_response可能会返回错误或者超时,避免合并流程中断:begin pdf_content = Net::HTTP.get_response(URI.parse(@task.assignable.pdf_file.try(:file).try(:url))).body pdf << CombinePDF.parse(pdf_content, allow_optional_content: true) rescue => e # 处理异常,比如记录日志或者给用户提示 Rails.logger.error("Failed to fetch PDF: #{e.message}") end - 如果合并的PDF文件很大,内存操作可能会有压力,这时候可以先把合并后的PDF存到临时文件,再附加到模型:
# 先保存到临时文件 temp_file = Tempfile.new(["combined", ".pdf"]) pdf.save(temp_file.path) # 再附加到模型 @task.combined_pdf.attach(io: temp_file, filename: "combined.pdf", content_type: "application/pdf") # 记得关闭并删除临时文件 temp_file.close temp_file.unlink
内容的提问来源于stack exchange,提问作者Uzair Nadeem
相关产品推荐
相关产品推荐

