use*_*833 7 validation ruby-on-rails image-uploading carrierwave ruby-on-rails-3.2
我使用CarrierWave,我想验证文件名,只允许上传文件的扩展名是否.gif,.png,.jpg,.jpeg,或者如果没有文件扩展名.
有时用户上传没有扩展名的文件.例如:
http://t2.gstatic.com/images?q=tbn:ANd9GcTCD2TLvYI8a4ChgBaYK_JaRfedvXLr3HXQfj0arXXAii3o2yjf
我知道有可能取消注释以下几行uploaders/image_uploader.rb,但我不知道另外说" 仅在有文件扩展名时允许任何这些扩展 "的方法.
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
#def extension_white_list
# %w(gif jpg jpeg png)
#end
Run Code Online (Sandbox Code Playgroud)
同样,在我的模型中,我有如下验证,但由于某种原因bad-extension.bad通过.
validates :image, allow_blank: true, format: {
with: %r{\.(gif|jpe?g|png)\z}i,
message: 'must be a GIF, JPG, or PNG'
}, if: :filename_has_extension?
def filename_has_extension?
image =~ /\./
end
Run Code Online (Sandbox Code Playgroud)
image不是String,而是属于ImageUploader( class ImageUploader < CarrierWave::Uploader::Base) 类。
因此这条线有问题:
image =~ /\./
Run Code Online (Sandbox Code Playgroud)
通过将其转换为 a 来更正它String:
image.to_s =~ /\./
Run Code Online (Sandbox Code Playgroud)
也就是说,更好的表达方式是:
!(image.to_s =~ /\.[a-z]{1,4}\z/).nil?
Run Code Online (Sandbox Code Playgroud)
它确保扩展名由一到四个a-z字符组成。另外,如果没有找到任何内容, =~就会返回nil,并且这一行会考虑到这一点。
如果未找到扩展名,=~则返回nil;所以.nil?会回来true;并将!其反转为false; 从而表明没有扩展。
另一方面,如果有扩展,=~则返回比赛开始的位置;哪个是0或更大,哪个不是 nil;所以.nil?会回来false;当 取反时!,true返回;从而表明存在扩展。