Forum: Ruby on Rails binary_to_string/string_to_binary confusion

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Mike L. (Guest)
on 2006-03-03 04:52
(Received via mailing list)
I am attempting to write a FrontBase activerecord adaptor.  I'm down
to only two unit tests failing, and one of them is binary_test.rb.

I can't figure out the logic of binary to string conversion.

Internally, I want the 'data' attribute to be a String object
identical to the contents of

  BINARY_FIXTURE_PATH = File.dirname(__FILE__) + '/fixtures/flowers.jpg'

When it gets written to the database, it should be hex-encoded similar
to the following:

INSERT INTO binaries ("id", "data") VALUES(1,

only with the hex portion being much larger.

I'm having trouble implementing binary_to_string and string_to_binary.

If I implement both of them to simply return value, then the first two
asserts pass:

assert @data ==, 'Newly assigned data differs from original'
assert @data ==, 'Data differs from original after save'

but the generated SQL is invalid because it attempts to insert raw
binary into the database.

If I implement them as follows:

      def self.hex_encode(value)
        retvalue = ""
        value.each_byte do |b|
          retvalue << sprintf("%02X", b)

      def self.hex_decode(value)
        retvalue = ""
        value.scan(/../) do |h|
          c = h.hex
          retvalue << c.chr

      def self.string_to_binary(value)
        value = self.hex_decode(value)

      def self.binary_to_string(value)
        value = self.hex_encode(value)

Then the first two tests still pass, but the third pass fails:
  1) Failure:
test_load_save(BinaryTest) [binary_test.rb:36]:
Reloaded data differs from original.
<false> is not true.

It is failing because it is storing the raw X'<hex digits>' data
instead of converting it back into binary.

Lookint at the code, it appears that database results pass through the
type_cast method to convert into native objects.  That code shows that
:binary column types pass through binary_to_string.  However, if I
implement binary_to_string to decode data fetched from the database,
then set accessors fail because for some reason they *also* call
binary_to_string when setting the value of data.  In one case, the
source data is hex-encoded and in one case it is not.  No matter how I
implement the method, it is going to break in one of the use cases.

I can't figure out where too hook in to convert the hex-encoded result
of the raw SQL select back into a raw data string without breaking the
first two asserts.

Can anyone point me to the correct path?

This topic is locked and can not be replied to.