Ben
Ben

Reputation: 173

Rails: using binary value to query a binary column returns nothing

I have a binary column which contains 256-bit checksums. I can store the checksums ok, but when I try to query via the checksum, nothing is returned.

d = Digest::SHA2.new
d.update "large str i'm creating the hash with"
begin
    codebase = Codebase.find_or_create_by_checksum(d.digest)
rescue ActiveRecord::StatementInvalid => e
    # handle duplicate record error
end

I've tried where and different versions of find. Nothing returns. When I use find_or_create_by_checksum, since it doesn't find anything it tries to create it and an exception is raised since I have a uniq index on the checksum column, but still I need to be able to get the record with the matching checksum.

    create_table :codebases do |t|
        t.binary :checksum, :null => false, :limit => 32
    end

    add_index :codebases, :checksum, :unique => true, :name => 'name_of_the_codebas_uniq_index'

Anybody know how to do this?

Upvotes: 0

Views: 3926

Answers (1)

daniel
daniel

Reputation: 9825

So if its binary on the database, I couldn't reproduce:

migration:

class Checksum < ActiveRecord::Migration
  def up
    create_table :checksums do |t|
        t.binary :checksum, :null => false, :limit => 32
    end
  end

  def down
  end
end

And then trying it on the rails console:

ruby-1.9.2-p290 :009 > Checksum.create(:checksum => digest.digest)
  SQL (0.4ms)  INSERT INTO "checksums" ("checksum") VALUES (?)  [["checksum", ",&\xB4kh\xFF\xC6\x8F\xF9\x9BE<\x1D0A4\x13B-pd\x83\xBF\xA0\xF9\x8A^\x88bf\xE7\xAE"]]
 => #<Checksum id: 1, checksum: ",&\xB4kh\xFF\xC6\x8F\xF9\x9BE<\x1D0A4\x13B-pd\x83\xBF\xA0\xF9\x8A^\x88bf\xE7\xAE"> 

ruby-1.9.2-p290 :010 > Checksum.first
  Checksum Load (0.2ms)  SELECT "checksums".* FROM "checksums" LIMIT 1
 => #<Checksum id: 1, checksum: ",&\xB4kh\xFF\xC6\x8F\xF9\x9BE<\x1D0A4\x13B-pd\x83\xBF\xA0\xF9\x8A^\x88bf\xE7\xAE"> 

ruby-1.9.2-p290 :011 > Checksum.find_by_checksum(digest.digest)
  Checksum Load (0.1ms)  SELECT "checksums".* FROM "checksums" WHERE "checksums"."checksum" = x'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae' LIMIT 1
 => #<Checksum id: 1, checksum: ",&\xB4kh\xFF\xC6\x8F\xF9\x9BE<\x1D0A4\x13B-pd\x83\xBF\xA0\xF9\x8A^\x88bf\xE7\xAE"> 

So it works as expected.....

Upvotes: 1

Related Questions