Ruby on Rails: декомпрессия (Zlib :: Deflate) не работает через определенное время - PullRequest
1 голос
/ 16 октября 2011

Мне нужно сжать большой кусок текста перед сохранением его в базу данных и распаковать его обратно, как только клиент запросит его.

Метод, который я сейчас использую, кажется, работает нормально, когда я вставляю новые записииспользуя консоль 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

1 Ответ

7 голосов
/ 16 октября 2011

Хорошо, на самом деле очень легко воспроизвести вашу проблему. В консоли рельсов сделайте следующее

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"

Причина повреждения заключается в том, что вы сжимаете уже сжатую строку

Вы, вероятно, должны изменить свой класс следующим образом, и у вас все будет в порядке

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

Теперь используйте ваш класс следующим образом

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" 
...