csv 通过回形针4连接时在S3中设置内容类型?

pprl5pva  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(67)

我尝试使用paperclip 4.1.1将CSV文件附加到Rails 3模型,但我无法获得S3报告的内容类型为text/csv(相反,我得到的是text/plain)。当我随后从S3下载文件时,扩展名被更改为与内容类型匹配,而不是保留原始扩展名(因此test.csv被下载为test.txt)。
从我所看到的,当你上传一个文件时,FileAdapter将在创建时缓存内容类型,内容类型的值由ContentTypeDetector(调用file -b --mime filename)确定。不幸的是,CSV文件返回text/plain,这是有道理的,因为你怎么才能真正区分这一点呢?尝试使用attachment.instance_write(:content_type, 'text/csv')设置content-type只会设置模型中的值,不会影响写入S3的内容。
FileAdapter的content_type在此处初始化:https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/io_adapters/file_adapter.rb#L14
创建io_adapter的调用:https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/attachment.rb#L98
我这里实际上有一个通用的上传(所以我不能在has_attached_file中的S3头定义中硬编码内容类型),而且我真的不想要内容类型欺骗保护。任何想法/建议?我宁愿不降级到3.5,因为这意味着只是推迟痛苦,但如果这是唯一的方法,我会接受它。

ltqd579y

ltqd579y1#

如果你使用fog,你可以这样做:

has_attached_file :report,
  fog_file: lambda { |attachment|
    {
      content_type: 'text/csv',
      content_disposition: "attachment; filename=#{attachment.original_filename}",
    }
  }

如果您使用Amazon S3作为您的存储提供商,则应该可以使用以下内容:

has_attached_file :report
  s3_headers: lambda { |attachment|
    { 
      'Content-Type' => 'text/csv',
      'Content-Disposition' => "attachment; filename=#{attachment.original_filename}",
    }
  }
0tdrvxhp

0tdrvxhp2#

最近遇到了这个问题,post进程和lambda都不工作,所以做了一个工作。与其他观察一样,当调用s3 lambda头时,附件的值为空。
1.将此线添加到模型中

attr_accessor :tmp_content_type, :tmp_file_name

1.覆盖文件赋值方法,这样我们就可以获取文件信息并将其存储以备后用

def file=(f)
  set_tmp_values(f.path)
  file.assign(f)
end

def set_tmp_values(file_path)
  self.tmp_file_name = File.basename(file_path)
  self.tmp_content_type = MIME::Types.type_for(file_path).first.content_type
end

1.使用临时变量

:s3_headers => lambda { |attachment|
  {
    'Content-Type' => attachment.tmp_content_type,
    "Content-Disposition" => "attachment; filename=\"# {attachment.tmp_file_name}\""
  }
}
yruzcnhs

yruzcnhs3#

我正在使用Paperclip 6.1.0和Rails 5.2.3,Ruby 2.6.6,这个答案使用了James Euangel在现有答案中提出的相同想法,但它更通用,并使用了猴子补丁。
我将在使用Paperclip::Attachment作为文件附件的模型上定义attr_accessors,并使用它们来设置传递给has_attached_file宏的s3_headers选项中的值。

# app/models/concerns/paperclip_attributes_maker.rb
# This concern defines attr_accessors for the paperclip attachment attributes of the ActiveRecord model

module PaperclipAttributesMaker
  extend ActiveSupport::Concern

  def self.included
    base.class_eval do
      base::PAPERCLIP_ATTACHMENT_ATTRS.each do |attachment_attr|
        attr_accessor "paperclip_#{attachment_attr}_content_type"
        attr_accessor "paperclip_#{attachment_attr}_filename"
      end
    end
  end
end

现在,我们需要对Paperclip::HasAttachaedFile类中定义的附件setter方法进行monkey-patch:

# app/initializers/patch_paperclip_has_attached_file.rb
# it patches paperclip/has_attached_file.rb

module Paperclip
  class HasAttachedFile
    def define_setter
      name = @name
      @klass.send :define_method, "#{@name}=" do |file|
        content_type = (file.content_type || MIME::Types.type_for(file.path).first.content_type) rescue nil
        instance_variable_set("@paperclip_#{name}_content_type", content_type)
        instance_variable_set("@paperclip_#{name}_filename", (file.original_filename rescue nil))
        send(name).assign(file)
      end
    end
  end
end

最后,我们声明Paperclip附件(我的意思是我们在ActiveRecord模型中得到了多少附件):

class StudentAttachment < ApplicationRecord
  PAPERCLIP_ATTACHMENT_ATTRS = [:attachment1, :attachment2]
  
  include PaperclipAttributesMaker # should be included after definition of PAPERCLIP_ATTACHMENT_ATTRS
  
  #...other code

  has_attached_file :attachment1, { # other options here
    s3_headers: lambda { |attachment|
      {
        'Content-Type' => attachment.paperclip_attachment1_content_type,
        "Content-Disposition" => "attachment; filename=\"#{attachment.paperclip_attachment1_filename}\""}}
      }

  has_attached_file :attachment2, { # other options here
    s3_headers: lambda { |attachment|
      {
        'Content-Type' => attachment.paperclip_attachment2_content_type,
        "Content-Disposition" => "attachment; filename=\"#{attachment.paperclip_attachment2_filename}\""}}
      }
end

相关问题