From c650341573243307fbe6f63702a9a4e4e289cfcd Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Tue, 10 May 2016 15:42:07 -0400 Subject: [PATCH] Fix ActiveRecord::LogSubscriber edge case If an attribute was of the binary type, and also was a Hash, it would previously not be logged, and instead raise an error saying that `bytesize` was not defined for the `attribute.value` (a `Hash`). Now, as is done on 4-2-stable, the attribute's database value is `bytesize`d, and then logged out to the terminal. Reproduction script: ```ruby require 'active_record' require 'minitest/autorun' require 'logger' ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') ActiveRecord::Base.logger = Logger.new(STDOUT) ActiveRecord::Schema.define do create_table :posts, force: true do |t| t.binary :preferences end end class Post < ActiveRecord::Base serialize :preferences end class BugTest < Minitest::Test def test_24955 Post.create!(preferences: {a: 1}) assert_equal 1, Post.count end end ``` --- activerecord/lib/active_record/log_subscriber.rb | 6 +++++- activerecord/test/cases/log_subscriber_test.rb | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb index efa2a4df027c..8e32af1c498d 100644 --- a/activerecord/lib/active_record/log_subscriber.rb +++ b/activerecord/lib/active_record/log_subscriber.rb @@ -22,7 +22,11 @@ def initialize def render_bind(attribute) value = if attribute.type.binary? && attribute.value - "<#{attribute.value.bytesize} bytes of binary data>" + if attribute.value.is_a?(Hash) + "<#{attribute.value_for_database.to_s.bytesize} bytes of binary data>" + else + "<#{attribute.value.bytesize} bytes of binary data>" + end else attribute.value_for_database end diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb index 707a2d1da1e9..c97960a412d0 100644 --- a/activerecord/test/cases/log_subscriber_test.rb +++ b/activerecord/test/cases/log_subscriber_test.rb @@ -215,5 +215,11 @@ def test_binary_data_is_not_logged wait assert_match(/<16 bytes of binary data>/, @logger.logged(:debug).join) end + + def test_binary_data_hash + Binary.create(data: { a: 1 }) + wait + assert_match(/<7 bytes of binary data>/, @logger.logged(:debug).join) + end end end