HornsAndHooves-flat_map 0.5.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/flat_map/errors.rb +1 -1
- data/lib/flat_map/model_mapper/associations.rb +148 -0
- data/lib/flat_map/model_mapper/persistence.rb +13 -1
- data/lib/flat_map/model_mapper.rb +2 -0
- data/lib/flat_map/open_mapper/associations.rb +19 -0
- data/lib/flat_map/open_mapper.rb +4 -2
- data/lib/flat_map/version.rb +3 -1
- data/spec/flat_map/mapper/mapping_spec.rb +2 -2
- data/spec/flat_map/mapper/mounting_spec.rb +1 -1
- data/spec/flat_map/mapper/persistence_spec.rb +15 -4
- data/spec/flat_map/mapper/targeting_spec.rb +15 -4
- data/spec/flat_map/model_mapper/associations_spec.rb +136 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd4f2b02c245613b8d3f3346d2355ae2108a4342ddb9f9cd1e268ef87310f1b8
|
4
|
+
data.tar.gz: fdf3bf9c4a4ffaa3c6647d907d0e02846eabbc60f5d9b593555d1904f371e72d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded272e0095638c4173d099651186dedd3116e1ac4532c0473d7dd6f126227026b55c6346728630fffe2580f483b5c0521c982a8bb0231eecc0917d498fa56e5
|
7
|
+
data.tar.gz: 20037626c6382fd471dff4db1a41f7ec09f81e7a5bbbe0ff80ffa6b1990bda10a1992dbf989da33e77ad1c0da7e0a9767bfff69a8ade32dfaf0abb08b9bda2e5
|
data/lib/flat_map/errors.rb
CHANGED
@@ -0,0 +1,148 @@
|
|
1
|
+
module FlatMap
|
2
|
+
# This module enhances and modifies original FlatMap::OpenMapper::Persistence
|
3
|
+
# functionality for ActiveRecord models as targets.
|
4
|
+
module ModelMapper::Associations
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
# Raised when there is no active record association between models.
|
8
|
+
class AssociationError < StandardError; end
|
9
|
+
|
10
|
+
# ModelMethods class macros
|
11
|
+
module ClassMethods
|
12
|
+
# Build relation for given traits.
|
13
|
+
# Allows to create relation which loads data from all tables related to given traits.
|
14
|
+
# For example:
|
15
|
+
#
|
16
|
+
# class CommentMapper < FlatMap::ModelMapper
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# class ArticleMapper < FlatMap::ModelMapper
|
20
|
+
# trait :with_comments do
|
21
|
+
# mount :comments, mapper_class: CommentMapper
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# Following call:
|
26
|
+
# ArticleMapper.relation(%i[with_comments]).where(...)
|
27
|
+
#
|
28
|
+
# is same as:
|
29
|
+
# Article.includes(:comments).where(...)
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# @param traits [Array<Symbol>]
|
33
|
+
# @return [ActiveRecord::Relation]
|
34
|
+
def relation(traits)
|
35
|
+
trait_associations = associations(traits)
|
36
|
+
target_class.includes(trait_associations).references(trait_associations)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return associations list for given traits based on current mapper mounting.
|
40
|
+
# This method allows to receive associations list for given traits.
|
41
|
+
# Then associations list could be used as parameters for .joins method
|
42
|
+
# to build active record relation to select data form tables related to traits.
|
43
|
+
# For example:
|
44
|
+
#
|
45
|
+
# class AuthorMapper < FlatMap::ModelMapper
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# class TagMapper < FlatMap::ModelMapper
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# class CommentMapper < FlatMap::ModelMapper
|
52
|
+
# trait :with_author do
|
53
|
+
# mount :author, mapper_class: AuthorMapper
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# class ArticleMapper < FlatMap::ModelMapper
|
58
|
+
# trait :with_comments do
|
59
|
+
# mount :comments, mapper_class: CommentMapper
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# trait :with_tags do
|
63
|
+
# mount :tags, mapper_class: TagMapper
|
64
|
+
# end
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# ArticleMapper.associations(%i[ with_comments ])
|
68
|
+
# => :comments
|
69
|
+
#
|
70
|
+
# ArticleMapper.associations(%i[ with_tags ])
|
71
|
+
# => :tags
|
72
|
+
#
|
73
|
+
# ArticleMapper.associations(%i[ with_comments with_tags ])
|
74
|
+
# => [:comments, :tags]
|
75
|
+
#
|
76
|
+
# ArticleMapper.associations(%i[ with_comments with_author ])
|
77
|
+
# => { comments: :author }
|
78
|
+
#
|
79
|
+
#
|
80
|
+
# @param traits [Array<Symbol>]
|
81
|
+
# @return [Array,Hash]
|
82
|
+
def associations(traits)
|
83
|
+
build_associations(traits, target_class, false)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Return associations list for given traits based on current mapper mounting.
|
87
|
+
#
|
88
|
+
# @param traits [Array<Symbol>]
|
89
|
+
# @param context [ActiveRecord::Base]
|
90
|
+
# @param include_self [Boolean]
|
91
|
+
# @return [Array,Hash]
|
92
|
+
protected def build_associations(traits, context, include_self)
|
93
|
+
classes_list = find_dependency_classes(traits)
|
94
|
+
|
95
|
+
map_classes_to_associations(context, classes_list, include_self)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Return associations list for given traits based on current mapper mounting.
|
99
|
+
#
|
100
|
+
# @param traits [Array<Symbol>]
|
101
|
+
# @return [Array<Symbol>]
|
102
|
+
private def find_dependency_classes(traits)
|
103
|
+
mountings.map do |mounting|
|
104
|
+
mapper_class = mounting.mapper_class
|
105
|
+
|
106
|
+
if mounting.traited?
|
107
|
+
mapper_class.build_associations(traits, target_class, false) if traits.include?(mounting.trait_name)
|
108
|
+
else
|
109
|
+
mapper_class.build_associations(traits, target_class, true)
|
110
|
+
end
|
111
|
+
end.compact
|
112
|
+
end
|
113
|
+
|
114
|
+
# Map given classes to association object names.
|
115
|
+
#
|
116
|
+
# @param context [ActiveRecord::Base]
|
117
|
+
# @param classes_list [Array<ActiveRecord::Base>]
|
118
|
+
# @param include_self [Boolean]
|
119
|
+
# @return [Symbol,Array,Hash,nil]
|
120
|
+
private def map_classes_to_associations(context, classes_list, include_self)
|
121
|
+
if classes_list.empty?
|
122
|
+
include_self ? association_for_class(context) : nil
|
123
|
+
else
|
124
|
+
classes_list = classes_list.first if classes_list.length == 1
|
125
|
+
|
126
|
+
include_self ? { association_for_class(context) => classes_list } : classes_list
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Return association name for target_class in given context.
|
131
|
+
#
|
132
|
+
# @param context [ActiveRecord::Base]
|
133
|
+
# #return [Symbol,nil]
|
134
|
+
private def association_for_class(context)
|
135
|
+
reflection = context.reflections.find do |_, reflection|
|
136
|
+
reflection.klass == target_class
|
137
|
+
end
|
138
|
+
|
139
|
+
unless reflection
|
140
|
+
raise AssociationError, "No association between #{context.name} and #{target_class.name} models."
|
141
|
+
end
|
142
|
+
|
143
|
+
reflection.first.to_sym
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
@@ -19,12 +19,24 @@ module FlatMap
|
|
19
19
|
# Find a record of the +target_class+ by +id+ and use it as a
|
20
20
|
# target for a new mapper, with a list of passed +traits+ applied
|
21
21
|
# to it.
|
22
|
+
# When `preload: true` option passed calls mapper `relation` method
|
23
|
+
# with traits list. This allows to load all related objects in one query.
|
22
24
|
#
|
23
25
|
# @param [#to_i] id of the record
|
24
26
|
# @param [*Symbol] traits
|
25
27
|
# @return [FlatMap::Mapper] mapper
|
26
28
|
def find(id, *traits, &block)
|
27
|
-
|
29
|
+
options = { preload: false }
|
30
|
+
|
31
|
+
options.merge!(traits.extract_options!)
|
32
|
+
|
33
|
+
if options[:preload]
|
34
|
+
record = relation(traits).find(id)
|
35
|
+
else
|
36
|
+
record = target_class.find(id)
|
37
|
+
end
|
38
|
+
|
39
|
+
new(record, *traits, &block)
|
28
40
|
end
|
29
41
|
|
30
42
|
# Fetch a class for the target of the mapper.
|
@@ -184,9 +184,11 @@ module FlatMap
|
|
184
184
|
class ModelMapper < OpenMapper
|
185
185
|
extend ActiveSupport::Autoload
|
186
186
|
|
187
|
+
autoload :Associations
|
187
188
|
autoload :Persistence
|
188
189
|
autoload :Skipping
|
189
190
|
|
191
|
+
include Associations
|
190
192
|
include Persistence
|
191
193
|
include Skipping
|
192
194
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module FlatMap
|
2
|
+
# This module enhances and modifies original FlatMap::OpenMapper::Persistence
|
3
|
+
# functionality for ActiveRecord models as targets.
|
4
|
+
module OpenMapper::Associations
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
# ModelMethods class macros
|
8
|
+
module ClassMethods
|
9
|
+
# Return association list for given traits.
|
10
|
+
# Used in ModelMapper.
|
11
|
+
#
|
12
|
+
# @return [nil]
|
13
|
+
def associations(*)
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/lib/flat_map/open_mapper.rb
CHANGED
@@ -16,6 +16,7 @@ module FlatMap
|
|
16
16
|
|
17
17
|
autoload :Mapping
|
18
18
|
autoload :Mounting
|
19
|
+
autoload :Associations
|
19
20
|
autoload :Traits
|
20
21
|
autoload :Factory
|
21
22
|
autoload :AttributeMethods
|
@@ -24,6 +25,7 @@ module FlatMap
|
|
24
25
|
|
25
26
|
include Mapping
|
26
27
|
include Mounting
|
28
|
+
include Associations
|
27
29
|
include Traits
|
28
30
|
include AttributeMethods
|
29
31
|
include ActiveModel::Validations
|
@@ -53,13 +55,13 @@ module FlatMap
|
|
53
55
|
# @param [Object] target Target of mapping
|
54
56
|
# @param [*Symbol] traits List of traits
|
55
57
|
# @raise [FlatMap::Mapper::NoTargetError]
|
56
|
-
def initialize(target, *traits)
|
58
|
+
def initialize(target, *traits, &block)
|
57
59
|
raise NoTargetError.new(self.class) unless target
|
58
60
|
|
59
61
|
@target, @traits = target, traits
|
60
62
|
|
61
63
|
if block_given?
|
62
|
-
singleton_class.trait :extension, &
|
64
|
+
singleton_class.trait :extension, &block
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
data/lib/flat_map/version.rb
CHANGED
@@ -35,10 +35,10 @@ module FlatMap
|
|
35
35
|
with({:attr_a => :attr_a, :mapped_attr_b => :attr_b}, {:writer => false}).
|
36
36
|
and_call_original
|
37
37
|
expect(Mapping::Factory).to receive(:new).
|
38
|
-
with(:attr_a, :attr_a, :writer => false).
|
38
|
+
with(:attr_a, :attr_a, { :writer => false }).
|
39
39
|
and_call_original
|
40
40
|
expect(Mapping::Factory).to receive(:new).
|
41
|
-
with(:mapped_attr_b, :attr_b, :writer => false).
|
41
|
+
with(:mapped_attr_b, :attr_b, { :writer => false }).
|
42
42
|
and_call_original
|
43
43
|
|
44
44
|
MappingSpec::EmptyMapper.class_eval do
|
@@ -76,7 +76,7 @@ module FlatMap
|
|
76
76
|
context 'defining mountings' do
|
77
77
|
it "should use Factory for defining mappings" do
|
78
78
|
expect(Mapper::Factory).to receive(:new).
|
79
|
-
with(:foo, :mapper_class_name => 'FooMapper').
|
79
|
+
with(:foo, { :mapper_class_name => 'FooMapper' }).
|
80
80
|
and_call_original
|
81
81
|
|
82
82
|
expect{ MountingSpec::EmptyMapper.mount(:foo, :mapper_class_name => 'FooMapper') }.
|
@@ -54,10 +54,21 @@ module FlatMap
|
|
54
54
|
describe '.find' do
|
55
55
|
let(:target){ PersistenceSpec::TargetClass.new('a', 'b') }
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
context "with preload" do
|
58
|
+
it 'should preload tables and find object for mapper' do
|
59
|
+
expect(PersistenceSpec::TargetClassMapper).to receive_message_chain(:relation, :find).
|
60
|
+
with([:used_trait]).with(1).and_return(target)
|
61
|
+
expect(PersistenceSpec::TargetClassMapper).to receive(:new).with(target, :used_trait)
|
62
|
+
PersistenceSpec::TargetClassMapper.find(1, :used_trait, preload: true)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "without preload" do
|
67
|
+
it 'should delegate to target class to find object for mapper' do
|
68
|
+
expect(PersistenceSpec::TargetClass).to receive(:find).with(1).and_return(target)
|
69
|
+
expect(PersistenceSpec::TargetClassMapper).to receive(:new).with(target, :used_trait)
|
70
|
+
PersistenceSpec::TargetClassMapper.find(1, :used_trait)
|
71
|
+
end
|
61
72
|
end
|
62
73
|
end
|
63
74
|
|
@@ -54,10 +54,21 @@ module FlatMap
|
|
54
54
|
describe '.find' do
|
55
55
|
let(:target){ ModelMethodsSpec::TargetClass.new('a', 'b') }
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
context "with preload" do
|
58
|
+
it 'should preload tables and find object for mapper' do
|
59
|
+
expect(ModelMethodsSpec::TargetClassMapper).to receive_message_chain(:relation, :find).
|
60
|
+
with([:used_trait]).with(1).and_return(target)
|
61
|
+
expect(ModelMethodsSpec::TargetClassMapper).to receive(:new).with(target, :used_trait)
|
62
|
+
ModelMethodsSpec::TargetClassMapper.find(1, :used_trait, preload: true)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "without preload" do
|
67
|
+
it 'should delegate to target class to find object for mapper' do
|
68
|
+
expect(ModelMethodsSpec::TargetClass).to receive(:find).with(1).and_return(target)
|
69
|
+
expect(ModelMethodsSpec::TargetClassMapper).to receive(:new).with(target, :used_trait)
|
70
|
+
ModelMethodsSpec::TargetClassMapper.find(1, :used_trait)
|
71
|
+
end
|
61
72
|
end
|
62
73
|
end
|
63
74
|
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module FlatMap
|
4
|
+
module AssociationsListSpec
|
5
|
+
# Simulate active record models.
|
6
|
+
# Only .reflections method is used.
|
7
|
+
Reflection = Struct.new(:klass)
|
8
|
+
|
9
|
+
class Author
|
10
|
+
def self.reflections; {}; end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Link
|
14
|
+
def self.reflections; {}; end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Tag
|
18
|
+
def self.reflections; {}; end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Category
|
22
|
+
def self.reflections; {}; end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Comment
|
26
|
+
# belongs_to :author
|
27
|
+
# has_many :links
|
28
|
+
|
29
|
+
def self.reflections
|
30
|
+
{
|
31
|
+
"author" => Reflection.new(Author),
|
32
|
+
"links" => Reflection.new(Link)
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Article
|
38
|
+
# has_many :comments
|
39
|
+
# has_many :tags
|
40
|
+
|
41
|
+
def self.reflections
|
42
|
+
{
|
43
|
+
"comments" => Reflection.new(Comment),
|
44
|
+
"tags" => Reflection.new(Tag)
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.joins(associations); end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Mappers for models.
|
52
|
+
class AuthorMapper < FlatMap::ModelMapper; end
|
53
|
+
|
54
|
+
class LinkMapper < FlatMap::ModelMapper; end
|
55
|
+
|
56
|
+
class TagMapper < FlatMap::ModelMapper; end
|
57
|
+
|
58
|
+
class CategoryMapper < FlatMap::ModelMapper; end
|
59
|
+
|
60
|
+
class CommentMapper < FlatMap::ModelMapper
|
61
|
+
trait :with_author do
|
62
|
+
mount :author, mapper_class: AuthorMapper
|
63
|
+
end
|
64
|
+
|
65
|
+
trait :with_links do
|
66
|
+
mount :links, mapper_class: LinkMapper
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class ArticleMapper < FlatMap::ModelMapper
|
71
|
+
trait :with_comments do
|
72
|
+
mount :comments, mapper_class: CommentMapper
|
73
|
+
end
|
74
|
+
|
75
|
+
trait :with_tags do
|
76
|
+
mount :tags, mapper_class: TagMapper
|
77
|
+
end
|
78
|
+
|
79
|
+
trait :with_category do
|
80
|
+
mount :category, mapper_class: CategoryMapper
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe ".relation" do
|
85
|
+
let(:relation) { double }
|
86
|
+
subject { ArticleMapper.relation(%i[ with_comments with_author ]) }
|
87
|
+
|
88
|
+
it "generates active record relation with correct associations" do
|
89
|
+
expect(Article).to receive_message_chain(:includes, :references).
|
90
|
+
with({ comments: :author }).with({ comments: :author }).
|
91
|
+
and_return(relation)
|
92
|
+
|
93
|
+
is_expected.to eq relation
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe ".associations" do
|
98
|
+
subject { ArticleMapper.associations(traits) }
|
99
|
+
|
100
|
+
context "one mounted class" do
|
101
|
+
let(:traits) { %i[ with_comments ] }
|
102
|
+
|
103
|
+
it { is_expected.to eq :comments }
|
104
|
+
end
|
105
|
+
|
106
|
+
context "nested mounted class" do
|
107
|
+
let(:traits) { %i[ with_comments with_author ] }
|
108
|
+
|
109
|
+
it { is_expected.to eq({ comments: :author }) }
|
110
|
+
end
|
111
|
+
|
112
|
+
context "mounted and nested mounted classes" do
|
113
|
+
let(:traits) { %i[ with_comments with_author with_tags ] }
|
114
|
+
|
115
|
+
it { is_expected.to eq([{ comments: :author }, :tags]) }
|
116
|
+
end
|
117
|
+
|
118
|
+
context "two nested mounted classes" do
|
119
|
+
let(:traits) { %i[ with_comments with_author with_links ] }
|
120
|
+
|
121
|
+
it { is_expected.to eq({ comments: [:author, :links] }) }
|
122
|
+
end
|
123
|
+
|
124
|
+
context "no relation between models" do
|
125
|
+
let(:traits) { %i[ with_category ] }
|
126
|
+
|
127
|
+
it do
|
128
|
+
expect { subject }.to raise_error(FlatMap::ModelMapper::Associations::AssociationError,
|
129
|
+
"No association between FlatMap::AssociationsListSpec::Article " \
|
130
|
+
"and FlatMap::AssociationsListSpec::Category models.")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HornsAndHooves-flat_map
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HornsAndHooves
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2024-01-09 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activesupport
|
@@ -149,9 +149,11 @@ files:
|
|
149
149
|
- lib/flat_map/mapping/writer/method.rb
|
150
150
|
- lib/flat_map/mapping/writer/proc.rb
|
151
151
|
- lib/flat_map/model_mapper.rb
|
152
|
+
- lib/flat_map/model_mapper/associations.rb
|
152
153
|
- lib/flat_map/model_mapper/persistence.rb
|
153
154
|
- lib/flat_map/model_mapper/skipping.rb
|
154
155
|
- lib/flat_map/open_mapper.rb
|
156
|
+
- lib/flat_map/open_mapper/associations.rb
|
155
157
|
- lib/flat_map/open_mapper/attribute_methods.rb
|
156
158
|
- lib/flat_map/open_mapper/factory.rb
|
157
159
|
- lib/flat_map/open_mapper/mapping.rb
|
@@ -181,6 +183,7 @@ files:
|
|
181
183
|
- spec/flat_map/mapping/writer/method_spec.rb
|
182
184
|
- spec/flat_map/mapping/writer/proc_spec.rb
|
183
185
|
- spec/flat_map/mapping_spec.rb
|
186
|
+
- spec/flat_map/model_mapper/associations_spec.rb
|
184
187
|
- spec/flat_map/open_mapper_spec.rb
|
185
188
|
- spec/spec_helper.rb
|
186
189
|
- tmp/metric_fu/_data/20131218.yml
|
@@ -204,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
207
|
- !ruby/object:Gem::Version
|
205
208
|
version: '0'
|
206
209
|
requirements: []
|
207
|
-
rubygems_version: 3.
|
210
|
+
rubygems_version: 3.1.6
|
208
211
|
signing_key:
|
209
212
|
specification_version: 4
|
210
213
|
summary: Deep object graph to a plain properties mapper
|
@@ -230,5 +233,6 @@ test_files:
|
|
230
233
|
- spec/flat_map/mapping/writer/method_spec.rb
|
231
234
|
- spec/flat_map/mapping/writer/proc_spec.rb
|
232
235
|
- spec/flat_map/mapping_spec.rb
|
236
|
+
- spec/flat_map/model_mapper/associations_spec.rb
|
233
237
|
- spec/flat_map/open_mapper_spec.rb
|
234
238
|
- spec/spec_helper.rb
|