Skip to content

Commit bd154d2

Browse files
authored
Merge pull request #432 from seanpdoyle/coder-activerecord
Add `activerecord` integration test coverage
2 parents b21bec6 + c80ab7f commit bd154d2

File tree

4 files changed

+108
-10
lines changed

4 files changed

+108
-10
lines changed

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ branch = ENV.fetch("BRANCH", "main")
88
gem "activesupport", github: "rails/rails", branch: branch
99
gem "activemodel", github: "rails/rails", branch: branch
1010
gem "activejob", github: "rails/rails", branch: branch
11+
gem "activerecord", github: "rails/rails", branch: branch
12+
gem "sqlite3", branch == "7-0-stable" ? "~> 1.4" : nil
1113

1214
gem "rubocop"
1315
gem "rubocop-minitest"

lib/active_resource/coder.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ module ActiveResource
99
# database. Decodes values read from the database into Active Resource
1010
# instances.
1111
#
12-
# class User < ActiveRecord::Base
13-
# serialize :person, coder: ActiveResource::Coder.new(Person)
14-
# end
15-
#
1612
# class Person < ActiveResource::Base
1713
# schema do
1814
# attribute :name, :string
1915
# end
2016
# end
2117
#
18+
# class User < ActiveRecord::Base
19+
# serialize :person, coder: Person
20+
# end
21+
#
2222
# user = User.new
2323
# user.person = Person.new name: "Matz"
2424
# user.person.name # => "Matz"
@@ -37,8 +37,8 @@ module ActiveResource
3737
#
3838
# user.person_before_type_cast # => "{\"name\":\"Matz\"}"
3939
#
40-
# To customize serialization, pass the method name or a block as the second
41-
# argument:
40+
# To customize serialization, pass the method name or a block that accepts the
41+
# instance as the second argument:
4242
#
4343
# person = Person.new name: "Matz"
4444
#
@@ -50,6 +50,10 @@ module ActiveResource
5050
class Coder
5151
attr_accessor :resource_class, :encoder
5252

53+
# ==== Arguments
54+
# * <tt>resource_class</tt> Active Resource class that to be coded
55+
# * <tt>encoder_method</tt> the method to invoke on the instance to encode
56+
# it. Defaults to ActiveResource::Base#encode.
5357
def initialize(resource_class, encoder_method = :encode, &block)
5458
@resource_class = resource_class
5559
@encoder = block || encoder_method

lib/active_resource/serialization.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ module ActiveResource
1111
# database. Decodes strings read from the database into Active Resource
1212
# instances.
1313
#
14-
# class User < ActiveRecord::Base
15-
# serialize :person, coder: Person
16-
# end
17-
#
1814
# class Person < ActiveResource::Base
1915
# schema do
2016
# attribute :name, :string
2117
# end
2218
# end
2319
#
20+
# class User < ActiveRecord::Base
21+
# serialize :person, coder: Person
22+
# end
23+
#
2424
# user = User.new
2525
# user.person = Person.new name: "Matz"
2626
#
@@ -57,6 +57,10 @@ module ActiveResource
5757
# end
5858
# end
5959
#
60+
# class User < ActiveRecord::Base
61+
# serialize :person, coder: ActiveResource::Coder.new(Person, :serializable_hash)
62+
# end
63+
#
6064
# user = User.new
6165
# user.person = Person.new name: "Matz"
6266
# user.person.name # => "Matz"

test/cases/base/serialization_test.rb

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,95 @@
33
require "abstract_unit"
44
require "fixtures/person"
55

6+
require "active_record"
7+
8+
ENV["DATABASE_URL"] = "sqlite3::memory:"
9+
10+
ActiveRecord::Base.establish_connection
11+
12+
ActiveRecord::Schema.define do
13+
create_table :users, force: true do |t|
14+
t.text :person_text
15+
t.json :person_json
16+
17+
t.check_constraint <<~SQL, name: "person_json_is_object"
18+
JSON_TYPE(person_json) = 'object'
19+
SQL
20+
end
21+
22+
create_table :teams, force: true do |t|
23+
t.text :people_text
24+
t.text :paginated_people_text
25+
t.json :people_json
26+
t.json :paginated_people_json
27+
28+
t.check_constraint <<~SQL, name: "people_json_is_object"
29+
JSON_TYPE(people_json) = 'array'
30+
SQL
31+
t.check_constraint <<~SQL, name: "paginated_people_json_is_object"
32+
JSON_TYPE(paginated_people_json) = 'object'
33+
SQL
34+
end
35+
end
36+
37+
class User < ActiveRecord::Base
38+
if ActiveSupport::VERSION::MAJOR < 8 && ActiveSupport::VERSION::MINOR < 1
39+
serialize :person_text, Person
40+
serialize :person_json, ActiveResource::Coder.new(Person, :serializable_hash)
41+
else
42+
serialize :person_text, coder: Person
43+
serialize :person_json, coder: ActiveResource::Coder.new(Person, :serializable_hash)
44+
end
45+
end
46+
647
class SerializationTest < ActiveSupport::TestCase
48+
include ActiveRecord::TestFixtures
49+
50+
test "dumps to a text column" do
51+
resource = Person.new({ id: 1, name: "Matz" }, true)
52+
53+
User.create!(person_text: resource)
54+
55+
user = User.sole
56+
assert_equal resource.to_json, user.person_text_before_type_cast
57+
end
58+
59+
test "dumps to a json column" do
60+
resource = Person.new({ id: 1, name: "Matz" }, true)
61+
62+
User.create!(person_json: resource)
63+
64+
user = User.sole
65+
assert_equal resource.serializable_hash.to_json, user.person_json_before_type_cast
66+
end
67+
68+
test "loads from a text column" do
69+
resource = Person.new(id: 1, name: "Matz")
70+
71+
User.connection.execute(<<~SQL)
72+
INSERT INTO users(person_text)
73+
VALUES ('#{resource.encode}')
74+
SQL
75+
76+
user = User.sole
77+
assert_predicate user.person_text, :persisted?
78+
assert_equal resource, user.person_text
79+
assert_equal resource.attributes, user.person_text.attributes
80+
end
81+
82+
test "loads from a json column" do
83+
resource = Person.new(id: 1, name: "Matz")
84+
85+
User.connection.execute(<<~SQL)
86+
INSERT INTO users(person_json)
87+
VALUES ('#{resource.encode}')
88+
SQL
89+
90+
user = User.sole
91+
assert_predicate user.person_json, :persisted?
92+
assert_equal resource, user.person_json
93+
assert_equal resource.attributes, user.person_json.attributes
94+
end
795
test ".load delegates to the .coder" do
896
resource = Person.new(id: 1, name: "Matz")
997

0 commit comments

Comments
 (0)