terrestrial 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile.lock +29 -24
- data/README.md +35 -17
- data/Rakefile +4 -9
- data/TODO.md +25 -18
- data/bin/test +31 -0
- data/docs/domain_object_contract.md +50 -0
- data/features/env.rb +4 -6
- data/features/example.feature +28 -28
- data/features/step_definitions/example_steps.rb +2 -2
- data/lib/terrestrial/adapters/memory_adapter.rb +241 -0
- data/lib/terrestrial/collection_mutability_proxy.rb +7 -2
- data/lib/terrestrial/dirty_map.rb +5 -0
- data/lib/terrestrial/error.rb +69 -0
- data/lib/terrestrial/graph_loader.rb +58 -35
- data/lib/terrestrial/graph_serializer.rb +37 -30
- data/lib/terrestrial/inspection_string.rb +19 -0
- data/lib/terrestrial/lazy_collection.rb +2 -2
- data/lib/terrestrial/lazy_object_proxy.rb +1 -1
- data/lib/terrestrial/many_to_one_association.rb +17 -11
- data/lib/terrestrial/public_conveniencies.rb +125 -95
- data/lib/terrestrial/relation_mapping.rb +30 -0
- data/lib/terrestrial/{mapper_facade.rb → relational_store.rb} +11 -1
- data/lib/terrestrial/version.rb +1 -1
- data/spec/config_override_spec.rb +10 -14
- data/spec/custom_serializers_spec.rb +4 -6
- data/spec/deletion_spec.rb +12 -14
- data/spec/error_handling/factory_error_handling_spec.rb +61 -0
- data/spec/error_handling/serialization_error_spec.rb +50 -0
- data/spec/error_handling/upsert_error_spec.rb +132 -0
- data/spec/graph_persistence_spec.rb +80 -24
- data/spec/graph_traversal_spec.rb +14 -6
- data/spec/new_graph_persistence_spec.rb +43 -9
- data/spec/object_identity_spec.rb +5 -7
- data/spec/ordered_association_spec.rb +4 -6
- data/spec/predefined_queries_spec.rb +4 -6
- data/spec/querying_spec.rb +4 -12
- data/spec/readme_examples_spec.rb +3 -6
- data/spec/{persistence_efficiency_spec.rb → sequel_query_efficiency_spec.rb} +101 -19
- data/spec/spec_helper.rb +24 -2
- data/spec/support/memory_adapter_test_support.rb +21 -0
- data/spec/support/{mapper_setup.rb → object_store_setup.rb} +5 -5
- data/spec/support/seed_data_setup.rb +3 -1
- data/spec/support/sequel_test_support.rb +58 -25
- data/spec/{sequel_mapper → terrestrial}/abstract_record_spec.rb +0 -0
- data/spec/{sequel_mapper → terrestrial}/collection_mutability_proxy_spec.rb +0 -0
- data/spec/{sequel_mapper → terrestrial}/deleted_record_spec.rb +0 -0
- data/spec/{sequel_mapper → terrestrial}/dirty_map_spec.rb +38 -6
- data/spec/{sequel_mapper → terrestrial}/lazy_collection_spec.rb +2 -3
- data/spec/{sequel_mapper → terrestrial}/lazy_object_proxy_spec.rb +0 -0
- data/spec/{sequel_mapper → terrestrial}/public_conveniencies_spec.rb +12 -7
- data/spec/{sequel_mapper → terrestrial}/upserted_record_spec.rb +0 -0
- data/{sequel_mapper.gemspec → terrestrial.gemspec} +3 -3
- metadata +47 -39
- data/lib/terrestrial/short_inspection_string.rb +0 -18
- data/spec/proxying_spec.rb +0 -88
- data/spec/support/mock_sequel.rb +0 -193
- data/spec/support/sequel_persistence_setup.rb +0 -19
@@ -1,3 +1,7 @@
|
|
1
|
+
require "terrestrial/error"
|
2
|
+
require "terrestrial/upserted_record"
|
3
|
+
require "terrestrial/deleted_record"
|
4
|
+
|
1
5
|
module Terrestrial
|
2
6
|
class RelationMapping
|
3
7
|
def initialize(name:, namespace:, fields:, primary_key:, factory:, serializer:, associations:, subsets:)
|
@@ -12,11 +16,18 @@ module Terrestrial
|
|
12
16
|
end
|
13
17
|
|
14
18
|
attr_reader :name, :namespace, :fields, :primary_key, :factory, :serializer, :associations, :subsets
|
19
|
+
private :factory, :serializer
|
15
20
|
|
16
21
|
def add_association(name, new_association)
|
17
22
|
@associations = associations.merge(name => new_association)
|
18
23
|
end
|
19
24
|
|
25
|
+
def load(record)
|
26
|
+
factory.call(record)
|
27
|
+
rescue => e
|
28
|
+
raise LoadError.new(namespace, factory, record, e)
|
29
|
+
end
|
30
|
+
|
20
31
|
def serialize(object, depth, foreign_keys = {})
|
21
32
|
object_attributes = serializer.call(object)
|
22
33
|
|
@@ -24,8 +35,18 @@ module Terrestrial
|
|
24
35
|
record(object_attributes, depth, foreign_keys),
|
25
36
|
extract_associations(object_attributes)
|
26
37
|
]
|
38
|
+
rescue => e
|
39
|
+
raise SerializationError.new(name, serializer, object, e)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete(object, depth)
|
43
|
+
object_attributes = serializer.call(object)
|
44
|
+
|
45
|
+
[deleted_record(object_attributes, depth)]
|
27
46
|
end
|
28
47
|
|
48
|
+
private
|
49
|
+
|
29
50
|
def record(attributes, depth, foreign_keys)
|
30
51
|
UpsertedRecord.new(
|
31
52
|
namespace,
|
@@ -35,6 +56,15 @@ module Terrestrial
|
|
35
56
|
)
|
36
57
|
end
|
37
58
|
|
59
|
+
def deleted_record(attributes, depth)
|
60
|
+
DeletedRecord.new(
|
61
|
+
namespace,
|
62
|
+
primary_key,
|
63
|
+
attributes,
|
64
|
+
depth,
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
38
68
|
def extract_associations(attributes)
|
39
69
|
Hash[
|
40
70
|
associations.map { |name, _association|
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require "terrestrial/graph_serializer"
|
2
2
|
require "terrestrial/graph_loader"
|
3
|
+
require "terrestrial/inspection_string"
|
3
4
|
|
4
5
|
module Terrestrial
|
5
|
-
class
|
6
|
+
class RelationalStore
|
6
7
|
include Enumerable
|
8
|
+
include InspectionString
|
7
9
|
|
8
10
|
def initialize(mappings:, mapping_name:, datastore:, dataset:, load_pipeline:, dump_pipeline:)
|
9
11
|
@mappings = mappings
|
@@ -133,5 +135,13 @@ module Terrestrial
|
|
133
135
|
object_load_pipeline: load_pipeline,
|
134
136
|
)
|
135
137
|
end
|
138
|
+
|
139
|
+
def inspectable_properties
|
140
|
+
[
|
141
|
+
:mapping_name,
|
142
|
+
:dataset,
|
143
|
+
:eager_load,
|
144
|
+
]
|
145
|
+
end
|
136
146
|
end
|
137
147
|
end
|
data/lib/terrestrial/version.rb
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "ostruct"
|
3
3
|
|
4
|
-
require "support/
|
5
|
-
require "support/sequel_persistence_setup"
|
4
|
+
require "support/object_store_setup"
|
6
5
|
require "support/seed_data_setup"
|
7
6
|
require "terrestrial"
|
8
7
|
|
9
8
|
require "terrestrial/configurations/conventional_configuration"
|
10
9
|
|
11
10
|
RSpec.describe "Configuration override" do
|
12
|
-
include_context "
|
13
|
-
include_context "sequel persistence setup"
|
11
|
+
include_context "object store setup"
|
14
12
|
include_context "seed data setup"
|
15
13
|
|
16
|
-
let(:
|
17
|
-
Terrestrial.
|
14
|
+
let(:object_store) {
|
15
|
+
Terrestrial.object_store(mappings: override_config, datastore: datastore)
|
18
16
|
}
|
19
17
|
|
20
18
|
let(:override_config) {
|
@@ -26,7 +24,7 @@ RSpec.describe "Configuration override" do
|
|
26
24
|
}
|
27
25
|
|
28
26
|
let(:user) {
|
29
|
-
|
27
|
+
object_store[:users].where(id: "users/1").first
|
30
28
|
}
|
31
29
|
|
32
30
|
context "override the root mapper factory" do
|
@@ -89,15 +87,13 @@ RSpec.describe "Configuration override" do
|
|
89
87
|
end
|
90
88
|
}
|
91
89
|
|
92
|
-
let(:datastore) { db_connection }
|
93
|
-
|
94
90
|
let(:unconventional_table_name) {
|
95
91
|
:users_is_called_this_weird_thing_perhaps_for_legacy_reasons
|
96
92
|
}
|
97
93
|
|
98
94
|
it "maps data from the specified relation" do
|
99
95
|
expect(
|
100
|
-
|
96
|
+
object_store[:users].map(&:id)
|
101
97
|
).to eq(["users/1", "users/2", "users/3"])
|
102
98
|
end
|
103
99
|
end
|
@@ -184,10 +180,10 @@ RSpec.describe "Configuration override" do
|
|
184
180
|
}
|
185
181
|
|
186
182
|
it "provides access to the same data via the different configs" do
|
187
|
-
expect(
|
188
|
-
expect(
|
189
|
-
expect(
|
190
|
-
expect(
|
183
|
+
expect(object_store[:t1_users].first.id).to eq("users/1")
|
184
|
+
expect(object_store[:t1_users].first).to be_a(TypeOneUser)
|
185
|
+
expect(object_store[:t2_users].first.id).to eq("users/1")
|
186
|
+
expect(object_store[:t2_users].first).to be_a(TypeTwoUser)
|
191
187
|
end
|
192
188
|
end
|
193
189
|
end
|
@@ -1,19 +1,17 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
require "support/have_persisted_matcher"
|
4
|
-
require "support/
|
5
|
-
require "support/sequel_persistence_setup"
|
4
|
+
require "support/object_store_setup"
|
6
5
|
require "support/seed_data_setup"
|
7
6
|
require "terrestrial"
|
8
7
|
|
9
8
|
require "terrestrial/configurations/conventional_configuration"
|
10
9
|
|
11
10
|
RSpec.describe "Config override" do
|
12
|
-
include_context "
|
13
|
-
include_context "sequel persistence setup"
|
11
|
+
include_context "object store setup"
|
14
12
|
include_context "seed data setup"
|
15
13
|
|
16
|
-
let(:user) {
|
14
|
+
let(:user) { object_store[:users].where(id: "users/1").first }
|
17
15
|
|
18
16
|
context "with an object that has private fields" do
|
19
17
|
let(:user_serializer) {
|
@@ -36,7 +34,7 @@ RSpec.describe "Config override" do
|
|
36
34
|
user.first_name = "This won't work"
|
37
35
|
user.last_name = "because the serialzer is weird"
|
38
36
|
|
39
|
-
|
37
|
+
object_store[:users].save(user)
|
40
38
|
|
41
39
|
expect(datastore).to have_persisted(:users, hash_including(
|
42
40
|
id: user.id,
|
data/spec/deletion_spec.rb
CHANGED
@@ -1,29 +1,27 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
require "support/
|
4
|
-
require "support/sequel_persistence_setup"
|
3
|
+
require "support/object_store_setup"
|
5
4
|
require "support/seed_data_setup"
|
6
5
|
require "support/have_persisted_matcher"
|
7
6
|
require "terrestrial"
|
8
7
|
|
9
8
|
RSpec.describe "Deletion" do
|
10
|
-
include_context "
|
11
|
-
include_context "sequel persistence setup"
|
9
|
+
include_context "object store setup"
|
12
10
|
include_context "seed data setup"
|
13
11
|
|
14
|
-
subject(:
|
12
|
+
subject(:user_store) { object_store[:users] }
|
15
13
|
|
16
14
|
let(:user) {
|
17
|
-
|
15
|
+
user_store.where(id: "users/1").first
|
18
16
|
}
|
19
17
|
|
20
18
|
let(:reloaded_user) {
|
21
|
-
|
19
|
+
user_store.where(id: "users/1").first
|
22
20
|
}
|
23
21
|
|
24
22
|
describe "Deleting the root" do
|
25
23
|
it "deletes the root object" do
|
26
|
-
|
24
|
+
user_store.delete(user, cascade: true)
|
27
25
|
|
28
26
|
expect(datastore).not_to have_persisted(
|
29
27
|
:users,
|
@@ -37,7 +35,7 @@ RSpec.describe "Deletion" do
|
|
37
35
|
end
|
38
36
|
|
39
37
|
it "deletes the root object" do
|
40
|
-
|
38
|
+
user_store.delete(user)
|
41
39
|
|
42
40
|
expect(datastore).not_to have_persisted(
|
43
41
|
:users,
|
@@ -47,7 +45,7 @@ RSpec.describe "Deletion" do
|
|
47
45
|
|
48
46
|
it "does not delete the child objects" do
|
49
47
|
expect {
|
50
|
-
|
48
|
+
user_store.delete(user)
|
51
49
|
}.not_to change { [datastore[:posts], datastore[:comments]].map(&:count) }
|
52
50
|
end
|
53
51
|
end
|
@@ -64,7 +62,7 @@ RSpec.describe "Deletion" do
|
|
64
62
|
|
65
63
|
it "deletes the specified node" do
|
66
64
|
user.posts.delete(post)
|
67
|
-
|
65
|
+
user_store.save(user)
|
68
66
|
|
69
67
|
expect(datastore).not_to have_persisted(
|
70
68
|
:posts,
|
@@ -74,7 +72,7 @@ RSpec.describe "Deletion" do
|
|
74
72
|
|
75
73
|
it "does not delete the parent object" do
|
76
74
|
user.posts.delete(post)
|
77
|
-
|
75
|
+
user_store.save(user)
|
78
76
|
|
79
77
|
expect(datastore).to have_persisted(
|
80
78
|
:users,
|
@@ -84,7 +82,7 @@ RSpec.describe "Deletion" do
|
|
84
82
|
|
85
83
|
it "does not delete the sibling objects" do
|
86
84
|
user.posts.delete(post)
|
87
|
-
|
85
|
+
user_store.save(user)
|
88
86
|
|
89
87
|
expect(reloaded_user.posts.count).to be > 0
|
90
88
|
end
|
@@ -92,7 +90,7 @@ RSpec.describe "Deletion" do
|
|
92
90
|
it "does not cascade delete" do
|
93
91
|
expect {
|
94
92
|
user.posts.delete(post)
|
95
|
-
|
93
|
+
user_store.save(user)
|
96
94
|
}.not_to change {
|
97
95
|
datastore[:comments].map { |r| r.fetch(:id) }
|
98
96
|
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "terrestrial"
|
2
|
+
require "terrestrial/configurations/conventional_configuration"
|
3
|
+
|
4
|
+
RSpec.describe "factory error handling" do
|
5
|
+
context "factory with too few parameters" do
|
6
|
+
before do
|
7
|
+
seed_user(record)
|
8
|
+
override_user_factory_with(no_parameters_factory)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:record) {
|
12
|
+
{
|
13
|
+
id: "users/999",
|
14
|
+
first_name: "Badger",
|
15
|
+
last_name: "Smith",
|
16
|
+
email: "b@smith.biz",
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
let(:no_parameters_factory) {
|
21
|
+
->() { }
|
22
|
+
}
|
23
|
+
|
24
|
+
it "raises a helpful error message" do
|
25
|
+
error = nil
|
26
|
+
begin
|
27
|
+
load_first_user
|
28
|
+
rescue Terrestrial::Error => error
|
29
|
+
end
|
30
|
+
|
31
|
+
expect(error.message).to eq(
|
32
|
+
[
|
33
|
+
"Error loading record from `users` relation `#{record.inspect}`.",
|
34
|
+
"Using: `#{no_parameters_factory.inspect}`.",
|
35
|
+
"Check that the factory is compatible.",
|
36
|
+
"Got Error: ArgumentError wrong number of arguments (given 1, expected 0)",
|
37
|
+
].join("\n")
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_first_user
|
43
|
+
@object_store[:users].first
|
44
|
+
end
|
45
|
+
|
46
|
+
def override_user_factory_with(factory)
|
47
|
+
config = Terrestrial.config(datastore)
|
48
|
+
.setup_mapping(:users) { |users|
|
49
|
+
users.factory(factory)
|
50
|
+
}
|
51
|
+
|
52
|
+
@object_store = Terrestrial.object_store(
|
53
|
+
mappings: config,
|
54
|
+
datastore: datastore,
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def seed_user(record)
|
59
|
+
datastore[:users].insert(record)
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "support/object_store_setup"
|
2
|
+
|
3
|
+
RSpec.describe "Serialization error handling" do
|
4
|
+
include_context "object store setup"
|
5
|
+
context "when a domain object is incompatible with its serializer" do
|
6
|
+
before do
|
7
|
+
override_user_serializer_with(incompatible_custom_serializer)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:user) { Object.new }
|
11
|
+
|
12
|
+
let(:incompatible_custom_serializer) {
|
13
|
+
->(x) { raise "I am incompatible" }
|
14
|
+
}
|
15
|
+
|
16
|
+
it "rescues and re-raises a more detailed error" do
|
17
|
+
error = nil
|
18
|
+
begin
|
19
|
+
save_user
|
20
|
+
rescue Terrestrial::SerializationError => error
|
21
|
+
end
|
22
|
+
|
23
|
+
expect(error.message).to eq(
|
24
|
+
[
|
25
|
+
"Error serializing object with mapping `users` `#{user.inspect}`.",
|
26
|
+
"Using serializer: `#{incompatible_custom_serializer.inspect}`.",
|
27
|
+
"Check the specified serializer can transform objects into a Hash.",
|
28
|
+
"Got Error: RuntimeError I am incompatible",
|
29
|
+
].join("\n")
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
# TODO: make configuration easier override
|
34
|
+
def override_user_serializer_with(serializer)
|
35
|
+
config = Terrestrial.config(datastore)
|
36
|
+
.setup_mapping(:users) { |users|
|
37
|
+
users.serializer(serializer)
|
38
|
+
}
|
39
|
+
|
40
|
+
@object_store = Terrestrial.object_store(
|
41
|
+
mappings: config,
|
42
|
+
datastore: datastore,
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def save_user
|
47
|
+
@object_store[:users].save(user)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require "support/object_store_setup"
|
2
|
+
require "terrestrial/inspection_string"
|
3
|
+
|
4
|
+
RSpec.describe "Upsert error handling" do
|
5
|
+
include_context "object store setup"
|
6
|
+
let(:user) { double(:user) }
|
7
|
+
|
8
|
+
context "with an record that raises error on persistence" do
|
9
|
+
before do
|
10
|
+
use_custom_serializer( ->(_) { unpersistable_record } )
|
11
|
+
end
|
12
|
+
let(:unpersistable_record) { UnpersistableRecord.new(original_error) }
|
13
|
+
let(:original_error) { RuntimeError.new("Cannot upsert") }
|
14
|
+
|
15
|
+
it "raises an UpsertError with detail of the original error" do
|
16
|
+
error = nil
|
17
|
+
begin
|
18
|
+
save_user
|
19
|
+
rescue Terrestrial::UpsertError => error
|
20
|
+
end
|
21
|
+
|
22
|
+
expect(error.message).to eq(
|
23
|
+
[
|
24
|
+
"Error upserting record into `users` with data `#{unpersistable_record}`.",
|
25
|
+
"Got Error: #{original_error.class} #{original_error.message}",
|
26
|
+
].join("\n")
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class UnpersistableRecord
|
32
|
+
include Terrestrial::InspectionString
|
33
|
+
|
34
|
+
def initialize(error)
|
35
|
+
@error = error
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
# This is used in error reporting
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def method_missing(*_)
|
44
|
+
# Raising on anything else ensures a problem while persisting
|
45
|
+
raise_if_upserting
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def raise_if_upserting
|
52
|
+
raise(@error) if caller.any? { |line| /if_upsert/ === line }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "serializer returns an extra field not in the schema" do
|
57
|
+
before do
|
58
|
+
use_custom_serializer(extra_field_serializer)
|
59
|
+
end
|
60
|
+
|
61
|
+
let(:extra_field_serializer) {
|
62
|
+
->(_x) {
|
63
|
+
{
|
64
|
+
extra_field_that_does_not_match_column: "some value",
|
65
|
+
id: "users/999",
|
66
|
+
first_name: "Hansel",
|
67
|
+
last_name: "Trickett",
|
68
|
+
email: "hansel@tricketts.org",
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
it "filters the serialization result and raises no error" do
|
74
|
+
expect { save_user }.not_to raise_error
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "serialization result omits required fields" do
|
79
|
+
before do
|
80
|
+
use_custom_serializer(missing_id_serializer)
|
81
|
+
end
|
82
|
+
|
83
|
+
let(:missing_id_serializer) {
|
84
|
+
->(_x) { serialization_result }
|
85
|
+
}
|
86
|
+
|
87
|
+
let(:serialization_result) {
|
88
|
+
object_attributes.reject { |k,v| k == :id }
|
89
|
+
}
|
90
|
+
|
91
|
+
let(:object_attributes) {
|
92
|
+
{
|
93
|
+
id: "users/999",
|
94
|
+
first_name: "Hansel",
|
95
|
+
last_name: "Trickett",
|
96
|
+
email: "hansel@tricketts.org",
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
it "raises an UpsertError with detail of the original error", backend: "sequel" do
|
101
|
+
error = nil
|
102
|
+
begin
|
103
|
+
save_user
|
104
|
+
rescue Terrestrial::UpsertError => error
|
105
|
+
end
|
106
|
+
|
107
|
+
expect(error.message).to eq(
|
108
|
+
[
|
109
|
+
"Error upserting record into `users` with data `#{serialization_result}`.",
|
110
|
+
"Got Error: Sequel::NotNullConstraintViolation PG::NotNullViolation: ERROR: null value in column \"id\" violates not-null constraint",
|
111
|
+
"DETAIL: Failing row contains (null, Hansel, Trickett, hansel@tricketts.org).\n",
|
112
|
+
].join("\n")
|
113
|
+
)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def save_user
|
118
|
+
@object_store[:users].save(user)
|
119
|
+
end
|
120
|
+
|
121
|
+
def use_custom_serializer(serializer)
|
122
|
+
config = Terrestrial.config(datastore)
|
123
|
+
.setup_mapping(:users) { |users|
|
124
|
+
users.serializer(serializer)
|
125
|
+
}
|
126
|
+
|
127
|
+
@object_store = Terrestrial.object_store(
|
128
|
+
mappings: config,
|
129
|
+
datastore: datastore,
|
130
|
+
)
|
131
|
+
end
|
132
|
+
end
|