验证模型

时间:2014-03-31 17:55:50

标签: ruby-on-rails model image-uploading

我有一个文件字段供想要上传个人资料图片的人使用:

<%= 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 以及相应的验证错误消息......

3 个答案:

答案 0 :(得分:1)

如果您愿意添加新的gem,那么我强烈建议您使用热门的Paperclip gem,它内置file sizecontent type/ extensionpresence的验证。

请参阅 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)

如果您要上传文件,则可能需要使用PaperclipCarrierwave。它们都备有功能,可以轻松实现您遇到的问题。

回形针:

您可以在模型中使用验证:

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