问题描述
我有模型附件,该模型对应于图像或其他类型的文件,我可以使用origin
字段来确定。 附件属于项目,我通过 AttachmentUploader 上传文件。
用户可以选择托管图片或文件。因此,根据用户单击的按钮,定义了image
或file
参数的两个不同按钮。
然后,我在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 (将#修改为@)