我正在使用 Shrine 直接上传到 S3,我正在尝试使用该pretty_location
插件在我的 S3 存储桶中设置位置。
我有一个文档模型具有file_data
text 属性并连接到 FileUploader:
class Document < ApplicationRecord
belongs_to :documentable, polymorphic: true
include FileUploader[:file]
validates :file, presence: true
end
其他模型通过以下关注点与文档模型相关联:
module Documentable
extend ActiveSupport::Concern
included do
has_one :document, as: :documentable, dependent: :destroy
accepts_nested_attributes_for :document, allow_destroy: true
end
end
这是我的文件上传器:
class FileUploader < Shrine
Attacher.promote { |data| PromoteJob.perform_later(data) }
Attacher.delete { |data| DeleteJob.perform_later(data) }
plugin :upload_options, cache: {acl: "public-read"}
plugin :upload_options, store: {acl: "public-read"}
plugin :logging, logger: Rails.logger
plugin :pretty_location
plugin :processing
plugin :delete_promoted
plugin :recache
plugin :restore_cached_data
plugin :delete_raw
plugin :validation_helpers
def generate_location(io, context = {})
# do something depending on context[:record].documentable
end
end
当通过客户端浏览器通过嵌套属性从用户的文件系统上传文件时,一切都按预期工作,我能够在我的 S3 存储桶中生成一个漂亮的位置。
但是,我有另一个模型,我试图将一个 PDF 文件上传到 S3,该文件是在后端使用以下设置生成的。
class Invoice < ApplicationRecord
has_one :documents, as: :documentable, dependent: :destroy
end
Invoice 模型不使用关注点,因为我希望它通过has_many
关联连接到多态文档。
class Api::V1::InvoicesController < Api::V1::BaseController
def upload_pdf
pdf = InvoicePdf.new(@invoice)
attachment = pdf.render
file = StringIO.new(attachment)
file.class.class_eval { attr_accessor :original_filename, :content_type }
file.original_filename = "invoice_#{@invoice.reference}.pdf"
file.content_type = "application/pdf"
@document = @invoice.documents.new(file: file)
if @document.save
render "documents/show.json", status: :created
else
render json: { errors: @document.errors }, status: :unprocessable_entity
end
end
end
上传工作正常,我可以将 PDF 上传到我的 S3 存储桶,但我无法生成漂亮的位置,因为当我在generate_location
方法内部时context[:record]
thedocumentable_type
和documentable_id
are nil
。
这是一个奇怪的行为,因为在 rails 控制台中,我可以通过运行Invoice.last.documents.file.url
.
我尝试以不同的方式创建文档记录,尝试使用documentable
适用于其他模型的相同关注点,但结果始终相同,我已经没有想法了。
有谁知道为什么documentable_type
anddocumentable_id
没有被传递到context
FileUploader 内的对象中?