Ruby on Rails:解压缩(Zlib :: Deflate)在一定时间后不起作用

Moo*_*oon 1 ruby mysql ruby-on-rails zlib ruby-on-rails-3

我需要在将大块文本保存到数据库之前压缩大块文本,并在客户端请求后将其解压缩.

当我使用Rails控制台插入新记录并立即查询新插入的记录时,我现在使用的方法似乎工作正常.即,我可以成功解压缩压缩的描述.

但是我无法解压缩description此日期之前添加的任何其他记录的压缩文件.对我来说真的很困惑,尤其是作为ROR世界的新手.

MySQL用作数据库.

你能指点我正确的方向吗?请看下面的模型,以便更好地理解它.

require "base64"

class Video < ActiveRecord::Base
  before_save :compress_description

  def desc
    unless description.blank?
      return decompress(description)
    end
  end

  private

  def compress_description
    unless description.blank?
      self.description = compress(description)
    end
  end

  def compress(text)
    Base64.encode64(Zlib::Deflate.new(nil, -Zlib::MAX_WBITS).deflate(text, Zlib::FINISH))
  end

  def decompress(text)
    Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(Base64.decode64(text))
  end
end
Run Code Online (Sandbox Code Playgroud)

Moi*_*aja 7

好吧,实际上很容易重现你的问题.在rails控制台中执行以下操作

Video.create(:description => "This is a test")
Video.last.description
=> "C8nILFYAokSFktTiEgA=\n" 
Video.last.desc
=> "This is a test" 
Video.last.save #This update corrupts the description
Video.last.desc
=> "C8nILFYAokSFktTiEgA=\n"
Run Code Online (Sandbox Code Playgroud)

发生损坏的原因是因为您正在压缩已经压缩的字符串

您应该按如下方式修改您的课程,您应该没事

require 'base64'
class Video < ActiveRecord::Base
  before_save :compress_description
  after_find :decompress_description
  attr_accessor :uncompressed_description

  private

  def compress_description
    unless @uncompressed_description.blank?
    self.description = compress(@uncompressed_description)
    end
  end

  def decompress_description
    unless description.blank?
      @uncompressed_description = decompress(description)
    end
  end

  def compress(text)
    Base64.encode64(Zlib::Deflate.new(nil, -Zlib::MAX_WBITS).deflate(text, Zlib::FINISH))
  end

  def decompress(text)
    Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(Base64.decode64(text))
  end
end
Run Code Online (Sandbox Code Playgroud)

现在使用您的课程如下

Video.create(:uncompressed_description => "This is a test")
Video.last.description
=> "C8nILFYAokSFktTiEgA=\n" 
Video.last.uncompressed_description
=> "This is a test" 
Video.last.save
Video.last.uncompressed_description
=> "This is a test" 
Run Code Online (Sandbox Code Playgroud)