Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 使用Rails和回形针处理文件附件和验证错误_Ruby On Rails_Ruby On Rails 3_Paperclip_Attachment - Fatal编程技术网

Ruby on rails 使用Rails和回形针处理文件附件和验证错误

Ruby on rails 使用Rails和回形针处理文件附件和验证错误,ruby-on-rails,ruby-on-rails-3,paperclip,attachment,Ruby On Rails,Ruby On Rails 3,Paperclip,Attachment,我有一个表格可以发送带有附件的邮件 用户选择要附加的文件 按submit并等待(很长时间),直到上传所有文件 用户忘记键入消息,因此验证失败 用户需要再次上传所有文件(长时间) 有没有简单的方法让rails记住已经上传的文件?(我一直在使用回形针)一种方法是在开始上载文件时,首先使用默认(传递)值创建消息对象,然后使用表单发出PUT请求以更新消息对象 通过这种方式,消息对象在创建时是有效的,您唯一要验证的是更新信息也是有效的(如果不是,消息将只具有默认值,用户不必重新上传文件) 您可以设置数

我有一个表格可以发送带有附件的邮件

  • 用户选择要附加的文件
  • 按submit并等待(很长时间),直到上传所有文件
  • 用户忘记键入消息,因此验证失败
  • 用户需要再次上传所有文件(长时间)

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

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

通过这种方式,
消息
对象在创建时是有效的,您唯一要验证的是更新信息也是有效的(如果不是,消息将只具有默认值,用户不必重新上传文件)

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

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

我不得不用回形针在最近的一个项目上修复这个问题。这有点粗糙,但它可以工作。我曾尝试在模型中使用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
视图:


这是个好主意。我现在正在做的是在没有验证的情况下强制保存,以防记录无效,但我想知道是否有更简单的方法。例如,与rails的自然行为类似,如果数据无效,表单中已经预先填充了用户已经输入的数据。如果需要这种行为,您必须切换到CarrierWave以将上载的文件保留在缓存中。回形针无法在验证错误期间保留已上载的文件,因此用户必须重新上载。如果你想继续使用回形针,我推荐我上面描述的那种设置。就我个人而言,我使用CarrierWave,它很容易设置。如果您想切换当前设置,这只是额外的工作。此外,缓存功能(用于已上载的文件)在Heroku上不起作用,因为它们具有只读文件系统。。。还有别的事情要考虑。它说剪纸是已经上演的。如果logo.staged?-->未定义的方法“staged”#
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: ''}