简体   繁体   English

验证失败时重新加载Paperclip文件

[英]Reload Paperclip file uploads when validation fails

I am new to rails. 我是铁杆新手。 I am currently setting up Paperclip for a model in Rails 3. When one of form fields fails validation, It fails to reload my uploaded image again.Its asks user to upload newly. 我目前正在为Rails 3中的模型设置Paperclip。当其中一个表单字段未通过验证时,它无法再次重新加载我上传的图像。它要求用户新上传。 It doesn't look user friendly. 它看起来不友好。

I would like to do two things to solve this issue. 我想做两件事来解决这个问题。 If all the fields are filled correctly I would like to store it in my app (system folder as usual paperclip does ).If fields fails validation, want to store the image in separate folder temporally until it get saved. 如果所有字段都正确填写我想将它存储在我的应用程序中(系统文件夹像往常一样回形针)。如果字段验证失败,想要暂时将图像存储在单独的文件夹中,直到它被保存。

Am I going in right path? 我正走在正确的道路上吗? Else is there any simple way to do this? 还有什么简单的方法吗?

Unfortunately, Paperclip saves the uploaded file only upon a successful save of the model containing the file. 不幸的是,只有在成功保存包含该文件的模型后,Paperclip才会保存上传的文件。

I believe the easiest option is to do the validation client-side with javascript so there is no need for all the back-end configuration/hacking. 我相信最简单的选择是使用javascript进行验证客户端,因此不需要所有的后端配置/黑客攻击。

I had to fix this on a recent project. 我不得不在最近的一个项目中解决这个问题。 It's a bit hacky but it works. 它有点hacky但它​​的工作原理。 I've tried calling cache_images() using after_validation and before_save in the model but it fails on create for some reason that I can't determine so I just call it from the controller instead. 我尝试在模型中使用after_validation和before_save调用cache_images(),但由于某些我无法确定的原因,它在创建时失败,所以我只是从控制器调用它。 Hopefully this saves someone else some time! 希望这能节省别人一些时间!

model: 模型:

class Shop < ActiveRecord::Base    
  attr_accessor :logo_cache

  has_attached_file :logo

  def cache_images
    if logo.staged?
      if invalid?
        FileUtils.cp(logo.queued_for_write[:original].path, logo.path(:original))
        @logo_cache = encrypt(logo.path(:original))
      end
    else
      if @logo_cache.present?
        File.open(decrypt(@logo_cache)) {|f| assign_attributes(logo: f)}
      end
    end
  end

  private

  def decrypt(data)
    return '' unless data.present?
    cipher = build_cipher(:decrypt, 'mypassword')
    cipher.update(Base64.urlsafe_decode64(data).unpack('m')[0]) + cipher.final
  end

  def encrypt(data)
    return '' unless data.present?
    cipher = build_cipher(:encrypt, 'mypassword')
    Base64.urlsafe_encode64([cipher.update(data) + cipher.final].pack('m'))
  end

  def build_cipher(type, password)
    cipher = OpenSSL::Cipher::Cipher.new('DES-EDE3-CBC').send(type)
    cipher.pkcs5_keyivgen(password)
    cipher
  end

end

controller: 控制器:

def create
  @shop = Shop.new(shop_params)
  @shop.user = current_user
  @shop.cache_images

  if @shop.save
    redirect_to account_path, notice: 'Shop created!'
  else
    render :new
  end
end

def update
  @shop = current_user.shop
  @shop.assign_attributes(shop_params)
  @shop.cache_images

  if @shop.save
    redirect_to account_path, notice: 'Shop updated.'
  else
    render :edit
  end
end

view: 视图:

= f.file_field :logo
= f.hidden_field :logo_cache

- if @shop.logo.file?
  %img{src: @shop.logo.url, alt: ''}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM