使用Rails和Paperclip文件附件和处理验证错误

时间:2011-12-29 23:18:38

标签: ruby-on-rails ruby-on-rails-3 paperclip attachment

我有一个表单来发送带附件的邮件。

  • 用户选择要附加的文件
  • 按提交并等待(长时间)直到所有文件上传
  • 用户忘记输入消息以便验证失败
  • 用户需要再次上传所有文件(长时间)

是否有一种简单的方法可以让rails记住已经上传的文件? (我一直在使用回形针)

2 个答案:

答案 0 :(得分:1)

一种方法是在开始上传文件时使用默认(传递)值创建Message对象,然后发出PUT请求以使用表单更新消息对象。

这样,Message对象在创建时有效,并且您唯一要验证的是更新信息也是有效的(如果不是,则消息将只具有默认值和用户不必重新上传文件。)

您可以设置数据库属性(通过Rails迁移)以设置默认值,这样您就不必在控制器中执行此操作。

change_column_default(:messages, :content, "You have a new message!")

答案 1 :(得分:0)

我必须在最近使用PaperClip的项目中解决此问题。它有点hacky但它​​的工作原理。我曾尝试在模型中使用after_validation和before_save调用cache_images(),但由于某些我无法确定的原因,它在创建时失败,所以我只是从控制器调用它。希望这能节省一些时间!

模型:

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

控制器:

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

视图:

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

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