在不存储附件的情况下使用回形针验证
Use Paperclip validations without storing the attachment
我正在构建一个 Rails 端点来代理不同的服务并映射来自所述服务的响应。主要问题是将文件附件的字节数据传递给该服务。
一个限制是我必须在传递文件之前对文件进行一些健全性检查。
我不需要将文件保存在我的 Rails 应用程序中,它仅用作其他服务的输入。
在一个非常简单的实现中,我只是从包装在 Tempfile
中的适当请求参数中读取字节,但这当然不需要完整性检查,因此还不够好。
我对执行 Paperclip 支持的验证类型很感兴趣,尤其是大小和内容类型,但我不想将实际文件存储在任何地方。
是否可以仅使用 Paperclip 的验证部分而不将附件存储在任何地方?
您可以使用 gem ruby-filemagic 验证文件 mime 类型:
FileMagic.new(FileMagic::MAGIC_MIME).file(your_tempfile.path) #=> "image/png; charset=binary"
您可以通过 your_tempfile.size
查看尺码
这就是我最终解决它的方式,深受 https://gist.github.com/basgys/5712426
的启发
因为我的项目已经在使用 Paperclip,所以我寻求基于它的解决方案,而不是包含更多的 gem。
首先,一个像这样的非持久化模型:
class Thumbnail
extend ActiveModel::Callbacks
include ActiveModel::Model
include Paperclip::Glue
ALLOWED_SIZE_RANGE = 1..1500.kilobytes.freeze
ALLOWED_CONTENT = ['image/jpeg'].freeze
# Paperclip required callbacks
define_model_callbacks :save, only: [:after]
define_model_callbacks :destroy, only: %i(before after)
attr_accessor :image_file_name,
:image_content_type,
:image_file_size,
:image_updated_at,
:id
has_attached_file :image
validates_attachment :image,
presence: true,
content_type: { content_type: ALLOWED_CONTENT },
size: { in: ALLOWED_SIZE_RANGE }
def errors
@errors ||= ActiveModel::Errors.new(self)
end
end
然后,将来自控制器的传入图像文件包装在该模型中:
class SomeController < ApplicationController
before_action :validate_thumbnail
def some_action
some_service.send(image_data)
end
private
def thumbnail
@thumbnail ||= Thumbnail.new(image: params.require(:image))
end
def validate_thumbnail
render_errors model: thumbnail if thumbnail.invalid?
end
def image_data
Paperclip.io_adapters.for(thumbnail.image).read
end
def some_service
# memoized service instance here
end
end
我正在构建一个 Rails 端点来代理不同的服务并映射来自所述服务的响应。主要问题是将文件附件的字节数据传递给该服务。
一个限制是我必须在传递文件之前对文件进行一些健全性检查。
我不需要将文件保存在我的 Rails 应用程序中,它仅用作其他服务的输入。
在一个非常简单的实现中,我只是从包装在 Tempfile
中的适当请求参数中读取字节,但这当然不需要完整性检查,因此还不够好。
我对执行 Paperclip 支持的验证类型很感兴趣,尤其是大小和内容类型,但我不想将实际文件存储在任何地方。
是否可以仅使用 Paperclip 的验证部分而不将附件存储在任何地方?
您可以使用 gem ruby-filemagic 验证文件 mime 类型:
FileMagic.new(FileMagic::MAGIC_MIME).file(your_tempfile.path) #=> "image/png; charset=binary"
您可以通过 your_tempfile.size
这就是我最终解决它的方式,深受 https://gist.github.com/basgys/5712426
的启发因为我的项目已经在使用 Paperclip,所以我寻求基于它的解决方案,而不是包含更多的 gem。
首先,一个像这样的非持久化模型:
class Thumbnail
extend ActiveModel::Callbacks
include ActiveModel::Model
include Paperclip::Glue
ALLOWED_SIZE_RANGE = 1..1500.kilobytes.freeze
ALLOWED_CONTENT = ['image/jpeg'].freeze
# Paperclip required callbacks
define_model_callbacks :save, only: [:after]
define_model_callbacks :destroy, only: %i(before after)
attr_accessor :image_file_name,
:image_content_type,
:image_file_size,
:image_updated_at,
:id
has_attached_file :image
validates_attachment :image,
presence: true,
content_type: { content_type: ALLOWED_CONTENT },
size: { in: ALLOWED_SIZE_RANGE }
def errors
@errors ||= ActiveModel::Errors.new(self)
end
end
然后,将来自控制器的传入图像文件包装在该模型中:
class SomeController < ApplicationController
before_action :validate_thumbnail
def some_action
some_service.send(image_data)
end
private
def thumbnail
@thumbnail ||= Thumbnail.new(image: params.require(:image))
end
def validate_thumbnail
render_errors model: thumbnail if thumbnail.invalid?
end
def image_data
Paperclip.io_adapters.for(thumbnail.image).read
end
def some_service
# memoized service instance here
end
end