Skip to content

Commit f424273

Browse files
committed
Move SQLite3 blob encoding to ActiveModel
1 parent d624a8e commit f424273

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

activemodel/lib/active_model/type/immutable_string.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,20 @@ def type
4646
def serialize(value)
4747
case value
4848
when ::Numeric, ::Symbol, ActiveSupport::Duration then value.to_s
49+
when ::String then serialize_cast_value(value)
4950
when true then @true
5051
when false then @false
5152
else super
5253
end
5354
end
5455

5556
def serialize_cast_value(value) # :nodoc:
57+
if value&.encoding == Encoding::BINARY
58+
# If we can treat the bytes as UTF-8 without changing them, then use UTF-8 as encoding
59+
new_value = value.dup.force_encoding(Encoding::UTF_8)
60+
return new_value if new_value.valid_encoding?
61+
end
62+
5663
value
5764
end
5865

activemodel/test/cases/type/immutable_string_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,26 @@ class ImmutableStringTest < ActiveModel::TestCase
1717
assert_same s, type.cast(s)
1818
assert_same s, type.deserialize(s)
1919
end
20+
21+
test "leaves validly encoded strings untouched" do
22+
s = "string with àccénts".encode(Encoding::ISO_8859_1)
23+
type = Type::ImmutableString.new
24+
assert_same s, type.serialize(s)
25+
end
26+
27+
test "serializes valid, binary-encoded strings to UTF-8" do
28+
s = "string with àccénts".b
29+
type = Type::ImmutableString.new
30+
serialized = type.serialize(s)
31+
assert_equal Encoding::UTF_8, serialized.encoding
32+
assert_equal s.bytes, serialized.bytes
33+
end
34+
35+
test "leaves true binary data untouched" do
36+
binary_data = "\xEE\x49\xC7".b
37+
type = Type::ImmutableString.new
38+
assert_same binary_data, type.serialize(binary_data)
39+
end
2040
end
2141
end
2242
end

activerecord/lib/active_record/connection_adapters/sqlite3/quoting.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,6 @@ def type_cast(value) # :nodoc:
7979
case value
8080
when BigDecimal
8181
value.to_f
82-
when String
83-
if value.encoding == Encoding::ASCII_8BIT
84-
super(value.encode(Encoding::UTF_8))
85-
else
86-
super
87-
end
8882
else
8983
super
9084
end

0 commit comments

Comments
 (0)