尝试使用amazon s3和carrierwave 项目信息

问题描述

出于未知原因,尝试在网络应用上托管文件时出现错误

我有模型附件,该模型对应于图像或其他类型的文件,我可以使用origin字段来确定。 附件属于项目,我通过 AttachmentUploader 上传文件

用户可以选择托管图片文件。因此,根据用户单击的按钮,定义了imagefile参数的两个不同按钮。

然后,我在origin字段上进行验证,以验证用户尝试上传文件确实与我们要托管的文件一致。

在本地存储中,我没有问题,并且文件已正确托管。但是,在heroku上托管的生产应用程序上,我正在通过carrierwave和amazon s3存储文件,并且发生了此错误

根据日志,尝试打开文件时出现错误TypeError (no implicit conversion of Aws::S3::Object into String),以便检查内容类型。

2020-09-30T20:43:03.185219+00:00 app[web.1]: I,[2020-09-30T20:43:03.185125 #4]  INFO -- : [9fb8796c-5513-4881-ba8c-77a871db3e08] Completed 500 Internal Server Error in 184ms (ActiveRecord: 2.4ms | Allocations: 4583)

2020-09-30T20:43:03.185964+00:00 app[web.1]: F,[2020-09-30T20:43:03.185892 #4] FATAL -- : [9fb8796c-5513-4881-ba8c-77a871db3e08]

2020-09-30T20:43:03.185965+00:00 app[web.1]: [9fb8796c-5513-4881-ba8c-77a871db3e08] TypeError (no implicit conversion of Aws::S3::Object into String):

2020-09-30T20:43:03.185966+00:00 app[web.1]: [9fb8796c-5513-4881-ba8c-77a871db3e08]

2020-09-30T20:43:03.185966+00:00 app[web.1]: [9fb8796c-5513-4881-ba8c-77a871db3e08] app/models/attachment.rb:36:in `initialize'

2020-09-30T20:43:03.185967+00:00 app[web.1]: [9fb8796c-5513-4881-ba8c-77a871db3e08] app/models/attachment.rb:36:in `open'

2020-09-30T20:43:03.185967+00:00 app[web.1]: [9fb8796c-5513-4881-ba8c-77a871db3e08] app/models/attachment.rb:36:in `check_content_type_origin'

2020-09-30T20:43:03.185967+00:00 app[web.1]: [9fb8796c-5513-4881-ba8c-77a871db3e08] app/controllers/attachments_controller.rb:55:in `create'

附件- app / models / attachment.rb

# @author despla_g
class Attachment < ApplicationRecord

  # An Attachment belongs to an Item
  belongs_to :item

  # An Attachment belongs to an User
  belongs_to :user

  # An Attachment can be an Image or a File
  enum origin: [:image,:file]

  # Fields attachment and origin must be filled
  validates_presence_of :attachment,:origin

  # Check attachment content type according to origin
  validate :check_content_type_origin,if: -> { attachment.present? }

  # An Attachment is hosted via carrierwave
  mount_uploader :attachment,AttachmentUploader

  # Check the content type of the attachment
  # According to the origin value
  def check_content_type_origin
    if origin == "image"
      errors.add(:attachment,"must be an image") if !MimeMagic.by_magic(File.open(attachment.file.file)).type.include?("image")
    elsif origin == "file"

      ##ERROR ON THE LINE BELOW
      errors.add(:attachment,"can't be an image") if MimeMagic.by_magic(File.open(attachment.file.file)).type.include?("image")



    end
  end

end

AttachmentUploader - app / uploaders / attachment_uploader.rb

# This file is the attachment uploader and allows to store all items file
class AttachmentUploader < CarrierWave::Uploader::Base

  # Allows to include MiniMagick
  # In order to use the resize_to_fill process
  include CarrierWave::MiniMagick

  # Allows to define the store_dir path
  # In order to store attachments at this path
  def store_dir
    "uploads/#{model.item.class.to_s.underscore}/#{model.origin}/#{model.item.id}/#{model.id}"
  end

  # Allows to create a specific version of the item image
  # In order to display the item image in the items card
  version :card,if: :is_image? do
    process resize_to_fill: [500,250]
  end

  # Allows to create a specific version of the item image
  # In order to display the item image in the items list
  version :list,if: :is_image? do
    process resize_to_fill: [50,50]
  end

  # Allows to check if the uploaded file is an image
  # In order to create specifics versions only for image file
  def is_image?(file = nil)
    file.content_type.to_s.include?("image") ? true : false
  end

end

CarrierWave - config / initializers / carrierwave.rb

CarrierWave.configure do |config|

  # Use local storage if in development or test
  if Rails.env.development? || Rails.env.test?
    config.storage = :file
  end

  # Use AWS storage if in production
  if Rails.env.production?
    if ENV['AWS_ACCESS_KEY'].present? && ENV['AWS_SECRET_KEY'].present? && ENV['AWS_BUCKET_NAME'].present? && ENV['AWS_REGION'].present?
      config.storage = :aws
      config.aws_bucket = ENV['AWS_BUCKET_NAME']
      config.aws_credentials = {
        access_key_id:  ENV['AWS_ACCESS_KEY'],# required
        secret_access_key: ENV['AWS_SECRET_KEY'],# required
        region: ENV['AWS_REGION']                                 # optional,defaults to 'us-east-1'
      }

      # The maximum period for authenticated_urls is only 7 days.
       config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7

       config.aws_attributes = -> { {
         expires: 1.week.from_Now.httpdate,cache_control: 'max-age=604800'
       } }
    else
      config.storage = :file
    end
  end

  config.cache_dir = "#{Rails.root}/tmp/uploads"                   # to let carrierWave work on heroku
end

项目信息

Ruby版本 2.7.1 轨道版本 6.0.3.2 数据库引擎 Postgresql

感谢阅读我。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)