我有一个文件字段供想要上传个人资料图片的人使用:
<%= f.file_field :file %>
一切正常,但是,我不知道如何验证它。
这是我的创建操作,并且它完全正常工作,但是像我正在做的那样拆分params哈希可能是错误的:
def create
new_user_params = user_params
image_params = user_params[:profile_image_attributes]
new_user_params.delete("profile_image_attributes")
@user = User.new(new_user_params)
respond_to do |format|
if @user.save
@user.create_thumbnail(image_params)
sign_in @user
format.html { redirect_to @user, notice: 'Welcome to ' + request.host_with_port + ', ' + @user.user_name + '!' }
format.json { render action: 'show', status: :created, location: @user }
else
format.html { render action: 'new' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
这是user#create_thumbnail
方法:
def create_thumbnail(data)
upload = data['file'].read
img = Magick::Image.from_blob(upload).first
img.resize!(75,75)
transaction do
self.create_profile_image(path: 'test')
img.write 'test' + '.' + img.format.downcase
end
end
问题:
就像它说的那样,一切都很完美,但我想知道如何正确地做到这一点,最重要的是,如何阻止人们上传巨大的文件和文件没有格式.gif,.png .jpg或.jpeg 以及相应的验证错误消息......
答案 0 :(得分:1)
如果您愿意添加新的gem,那么我强烈建议您使用热门的Paperclip
gem,它内置file size
,content type/ extension
和presence
的验证。
请参阅 Paperclip Github 文档。
就像说
一样简单validates_attachment :image, :presence => true,
:content_type => { :content_type => ["image/jpg", "image/jpeg", "image/gif", "image/png"] },
:size => { :in => 0..10.kilobytes }
对于名为image
的字段的模型(Paperclip附件)。
<强>其中:强>
:presence
验证表单提交时附加了文件
:content_type
验证指定的文件扩展名(mime-type)。它还会检查上传文件的实际内容。阅读我的 findings here。
:size
根据给定范围验证上传的文件大小。
答案 1 :(得分:0)
如果您要上传文件,则可能需要使用Paperclip或Carrierwave。它们都备有功能,可以轻松实现您遇到的问题。
回形针:
您可以在模型中使用验证:
validates_attachment_presence
validates_attachment_content_type
validates_attachment_size
旧的RailsCast特色回形针:http://railscasts.com/episodes/134-paperclip
Carrierwave:
您是否指定了上传者类,并从那里可以添加文件类型和大小的验证。
class MyUploader < CarrierWave::Uploader::Base
def extension_white_list
%w(jpg jpeg gif png)
end
end
以Carrierwave为特色的旧RailsCast:http://railscasts.com/episodes/253-carrierwave-file-uploads
答案 2 :(得分:0)
为什么不使用宝石作为载波? https://github.com/carrierwaveuploader/carrierwave
如果你想使用你的代码,为什么不重构一下,例如
我会使用一些设计模式做这样的事情。
def create_thumbnail
upload_file(read_file(data))
resize_img
execute_transaction
end
def read_file(data)
data['file'].read
end
def upload_file(read_file)
Magick::Image.from_blob(read_file).first
end
def resize_img
upload_file.resize!(75,75)
end
def execute_transaction
transaction do
self.create_profile_image(path: 'test')
img.write 'test' + '.' + img.format.downcase
end
end