Skip to content

Commit 9912d0a

Browse files
committed
Integrate with Active Record
First, register the `ActiveModel::Type::Collection` with `ActiveRecord::Type`. Next, add test coverage for writing to and reading from a `TEXT` and `JSON` column.
1 parent 254e166 commit 9912d0a

3 files changed

Lines changed: 60 additions & 0 deletions

File tree

activemodel/lib/active_model/type/collection.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def serialize(value)
4848
end
4949

5050
def deserialize(value)
51+
return nil if value.nil?
52+
5153
serializer.decode(value).map { |el| @type_object.deserialize(el) }
5254
end
5355

@@ -66,6 +68,8 @@ def changed_in_place?(raw_old_value, new_value)
6668
end
6769

6870
def valid_value?(value)
71+
return true if value.nil?
72+
6973
value.is_a?(Array) && value.all? { |el| @type_object.valid_value?(el) }
7074
end
7175

activerecord/lib/active_record/type.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def current_adapter_name
5959
BigInteger = ActiveModel::Type::BigInteger
6060
Binary = ActiveModel::Type::Binary
6161
Boolean = ActiveModel::Type::Boolean
62+
Collection = ActiveModel::Type::Collection
6263
Decimal = ActiveModel::Type::Decimal
6364
Float = ActiveModel::Type::Float
6465
Integer = ActiveModel::Type::Integer
@@ -69,6 +70,7 @@ def current_adapter_name
6970
register(:big_integer, Type::BigInteger, override: false)
7071
register(:binary, Type::Binary, override: false)
7172
register(:boolean, Type::Boolean, override: false)
73+
register(:collection, Type::Collection, override: false)
7274
register(:date, Type::Date, override: false)
7375
register(:datetime, Type::DateTime, override: false)
7476
register(:decimal, Type::Decimal, override: false)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# frozen_string_literal: true
2+
3+
require "cases/helper"
4+
5+
class CollectionAttributeTest < ActiveRecord::TestCase
6+
self.use_transactional_tests = false
7+
8+
class CollectionDataTypeOnText < ActiveRecord::Base
9+
attribute :integers, :collection, element_type: :integer
10+
end
11+
12+
class CollectionDataTypeOnJson < ActiveRecord::Base
13+
attribute :integers, :collection, element_type: :integer
14+
end
15+
16+
setup do
17+
@connection = ActiveRecord::Base.lease_connection
18+
@connection.create_table(CollectionDataTypeOnText.table_name, force: true) { |t| t.text :integers }
19+
@connection.create_table(CollectionDataTypeOnJson.table_name, force: true) { |t| t.json :integers }
20+
end
21+
22+
teardown do
23+
@connection.drop_table CollectionDataTypeOnText.table_name, if_exists: true
24+
@connection.drop_table CollectionDataTypeOnJson.table_name, if_exists: true
25+
CollectionDataTypeOnText.reset_column_information
26+
CollectionDataTypeOnJson.reset_column_information
27+
end
28+
29+
test "writes :collection attribute instance to text column" do
30+
integers = ["1", "2", "3"]
31+
record = CollectionDataTypeOnText.create!(integers: integers)
32+
33+
assert_equal integers.map(&:to_i), record.integers
34+
end
35+
36+
test "writes :collection attribute instance to json column" do
37+
integers = ["1", "2", "3"]
38+
record = CollectionDataTypeOnJson.create!(integers: integers)
39+
40+
assert_equal integers.map(&:to_i), record.integers
41+
end
42+
43+
test "reads nil :collection attribute instance from text column" do
44+
record = CollectionDataTypeOnText.create!(integers: nil)
45+
46+
assert_empty record.integers
47+
end
48+
49+
test "reads nil :collection attribute instance from json column" do
50+
record = CollectionDataTypeOnJson.create!(integers: nil)
51+
52+
assert_empty record.integers
53+
end
54+
end

0 commit comments

Comments
 (0)