flat_map 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +31 -0
- data/.metrics +17 -0
- data/.rspec +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +20 -0
- data/LICENSE +20 -0
- data/README.markdown +211 -0
- data/Rakefile +15 -0
- data/flat_map.gemspec +30 -0
- data/lib/flat_map.rb +9 -0
- data/lib/flat_map/base_mapper.rb +95 -0
- data/lib/flat_map/base_mapper/attribute_methods.rb +54 -0
- data/lib/flat_map/base_mapper/factory.rb +238 -0
- data/lib/flat_map/base_mapper/mapping.rb +123 -0
- data/lib/flat_map/base_mapper/mounting.rb +168 -0
- data/lib/flat_map/base_mapper/persistence.rb +145 -0
- data/lib/flat_map/base_mapper/skipping.rb +62 -0
- data/lib/flat_map/base_mapper/traits.rb +94 -0
- data/lib/flat_map/empty_mapper.rb +29 -0
- data/lib/flat_map/errors.rb +57 -0
- data/lib/flat_map/mapper.rb +213 -0
- data/lib/flat_map/mapper/skipping.rb +45 -0
- data/lib/flat_map/mapper/targeting.rb +130 -0
- data/lib/flat_map/mapping.rb +124 -0
- data/lib/flat_map/mapping/factory.rb +21 -0
- data/lib/flat_map/mapping/reader.rb +12 -0
- data/lib/flat_map/mapping/reader/basic.rb +28 -0
- data/lib/flat_map/mapping/reader/formatted.rb +45 -0
- data/lib/flat_map/mapping/reader/formatted/formats.rb +28 -0
- data/lib/flat_map/mapping/reader/method.rb +25 -0
- data/lib/flat_map/mapping/reader/proc.rb +15 -0
- data/lib/flat_map/mapping/writer.rb +11 -0
- data/lib/flat_map/mapping/writer/basic.rb +25 -0
- data/lib/flat_map/mapping/writer/method.rb +28 -0
- data/lib/flat_map/mapping/writer/proc.rb +18 -0
- data/lib/flat_map/version.rb +3 -0
- data/spec/flat_map/empty_mapper_spec.rb +36 -0
- data/spec/flat_map/errors_spec.rb +23 -0
- data/spec/flat_map/mapper/attribute_methods_spec.rb +36 -0
- data/spec/flat_map/mapper/callbacks_spec.rb +76 -0
- data/spec/flat_map/mapper/factory_spec.rb +258 -0
- data/spec/flat_map/mapper/mapping_spec.rb +98 -0
- data/spec/flat_map/mapper/mounting_spec.rb +142 -0
- data/spec/flat_map/mapper/skipping_spec.rb +91 -0
- data/spec/flat_map/mapper/targeting_spec.rb +156 -0
- data/spec/flat_map/mapper/traits_spec.rb +172 -0
- data/spec/flat_map/mapper/validations_spec.rb +72 -0
- data/spec/flat_map/mapper_spec.rb +9 -0
- data/spec/flat_map/mapping/factory_spec.rb +12 -0
- data/spec/flat_map/mapping/reader/basic_spec.rb +15 -0
- data/spec/flat_map/mapping/reader/formatted_spec.rb +62 -0
- data/spec/flat_map/mapping/reader/method_spec.rb +13 -0
- data/spec/flat_map/mapping/reader/proc_spec.rb +13 -0
- data/spec/flat_map/mapping/writer/basic_spec.rb +15 -0
- data/spec/flat_map/mapping/writer/method_spec.rb +13 -0
- data/spec/flat_map/mapping/writer/proc_spec.rb +13 -0
- data/spec/flat_map/mapping_spec.rb +123 -0
- data/spec/spec_helper.rb +7 -0
- data/tmp/metric_fu/_data/20131218.yml +6902 -0
- data/tmp/metric_fu/_data/20131219.yml +6726 -0
- metadata +184 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjNmMzU5MGI0NjIwZGQyZmY4YzBlM2RhYzFmYTMzNGJmM2ZiMzIzMA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NjAxZjRjYThiNWMxN2QwN2NkMWNkODFhZDg0NjEzZDQ0MGE5YWM5ZQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
N2M2NmQzZmFkMjZjMjg3NThmZjhjN2I0YmI2NGMyMWQxZTcyNTYwYTFmNzJj
|
10
|
+
NmM0Yzc1NDg4YWM1MmM1ZGE3ZTA3MTUzZTNmNjgwZGZkZDYxN2ViMzliNDVl
|
11
|
+
NWQ4Yjg3ZDI5NTg2MmZiOTQ2ZjQ5ODk1YTUwODQyN2JmNzIxNDQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZTg1ZmI2NzY1NjA3ZGYyYzQ1NTAwYzFlMDUxODY2Y2M5YmNlMWI5YTNkNWYx
|
14
|
+
MTI5NGQwNDA5YmQwOTNjOTJiYmRhZDdjYWY0YTkwMzU4MzQxM2FlYjU5Nzgy
|
15
|
+
YzlkYmEzNmNlM2ExNTA5M2E5Y2E1OGFlNDViYmU1MGVmYzg5M2U=
|
data/.gitignore
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# SimpleCov generated
|
2
|
+
coverage
|
3
|
+
coverage.data
|
4
|
+
|
5
|
+
# rdoc generated
|
6
|
+
rdoc
|
7
|
+
|
8
|
+
# yard generated
|
9
|
+
doc
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# bundler
|
13
|
+
.bundle
|
14
|
+
|
15
|
+
# jeweler generated
|
16
|
+
pkg
|
17
|
+
|
18
|
+
*.gem
|
19
|
+
Gemfile.lock
|
20
|
+
|
21
|
+
# For MacOS:
|
22
|
+
.DS_Store
|
23
|
+
|
24
|
+
# exclude everything in tmp
|
25
|
+
tmp/*
|
26
|
+
# except the metric_fu directory
|
27
|
+
!tmp/metric_fu/
|
28
|
+
# but exclude everything *in* the metric_fu directory
|
29
|
+
tmp/metric_fu/*
|
30
|
+
# except for the _data directory to track metrical outputs
|
31
|
+
!tmp/metric_fu/_data/
|
data/.metrics
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
MetricFu::Configuration.run do |config|
|
2
|
+
[ :rcov,
|
3
|
+
:rails_best_practices
|
4
|
+
].each do |metric|
|
5
|
+
config.configure_metric(metric) do |m|
|
6
|
+
m.enabled = false
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
config.configure_metric(:cane) do |cane|
|
11
|
+
cane.line_length = 100
|
12
|
+
end
|
13
|
+
|
14
|
+
config.configure_metric(:flay) do |flay|
|
15
|
+
flay.minimum_score = 10
|
16
|
+
end
|
17
|
+
end
|
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
flat_map
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3-p448
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in flat_map.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem 'redcarpet'
|
8
|
+
gem 'yard'
|
9
|
+
gem 'pry'
|
10
|
+
end
|
11
|
+
|
12
|
+
group :development, :test do
|
13
|
+
# code metrics:
|
14
|
+
gem "metric_fu"
|
15
|
+
end
|
16
|
+
|
17
|
+
group :test do
|
18
|
+
gem 'simplecov' , :require => false
|
19
|
+
gem 'simplecov-rcov-text', :require => false
|
20
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 TMXCredit, authors Artem Kuzko, Zachary Belzer, Sergey Potapov
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
# FlatMap
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/TMXCredit/flat_map.png)](http://travis-ci.org/TMXCredit/flat_map)
|
4
|
+
|
5
|
+
FlatMap is a flexible tool for mapping a complex, deeply nested object graph
|
6
|
+
into a mapper object with all mapped attributes accessible in a plain way.
|
7
|
+
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
### Mapper
|
12
|
+
|
13
|
+
FlatMap mappers are designed to provide complex set of data, distributed over
|
14
|
+
associated AR models, in the simple form of a plain hash. They accept a plain
|
15
|
+
hash of the same format and distribute its values over deeply nested AR models.
|
16
|
+
To achieve this goal, Mapper uses three major concepts: Mappings, Mountings and
|
17
|
+
Traits.
|
18
|
+
|
19
|
+
### Mappings
|
20
|
+
|
21
|
+
Mappings are defined view `Mapper.map` method. They represent a simple one-to-one
|
22
|
+
relation between target attribute and a mapper, extended by additional features
|
23
|
+
for convenience. The best way to show how they work is by example:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
class CustomerMapper < FlatMap::Mapper
|
27
|
+
# When there is no need to rename attributes, they can be passed as array:
|
28
|
+
map :first_name, :last_name
|
29
|
+
# When hash is used, it will map field name to attribute name:
|
30
|
+
map :dob => :date_of_birth
|
31
|
+
# Also, additional options can be used:
|
32
|
+
map :name_suffix, :format => :enum
|
33
|
+
map :password, :reader => false, :writer => :assign_password
|
34
|
+
# Or you can combine all definitions together if they all are common:
|
35
|
+
map :first_name, :last_name,
|
36
|
+
:dob => :date_of_birth,
|
37
|
+
:suffix => :name_suffix,
|
38
|
+
:reader => :my_custom_reader
|
39
|
+
end
|
40
|
+
```
|
41
|
+
When mappings are defined, one can read and write values using them:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
mapper = CustomerMapper.find(1)
|
45
|
+
mapper.read # => {:first_name => 'John', :last_name => 'Smith', :dob => '02/01/1970'}
|
46
|
+
mapper.write(params) # will assign same-looking hash of arguments
|
47
|
+
```
|
48
|
+
|
49
|
+
Following options may be used when defining mappings:
|
50
|
+
|
51
|
+
* `:format` Allows to additionally process output value on reading it. All formats are
|
52
|
+
defined within `FlatMap::Mapping::Reader::Formatted::Formats` and
|
53
|
+
specify the actual output of the mapping
|
54
|
+
* `:reader` Allows you to manually control reader value of a mapping, or a group of
|
55
|
+
mappings listed on definition. When String or Symbol is used, will call
|
56
|
+
a method, defined by mapper class, and pass mapping object to it. When
|
57
|
+
lambda is used, mapper's target (the model) will be passed to it.
|
58
|
+
* `:writer` Just like with the :reader option, allows to control how value is assigned
|
59
|
+
(written). Works the same way as :reader does, but additionally value is
|
60
|
+
sent to both mapper method and lambda.
|
61
|
+
* `:multiparam` If used, multiparam attributes will be extracted from params, when
|
62
|
+
those are passed for writing. Class should be passed as a value for
|
63
|
+
this option. Object of this class will be initialized with the arguments
|
64
|
+
extracted from params hash.
|
65
|
+
|
66
|
+
### Mountings
|
67
|
+
|
68
|
+
Mappers may be mounted on top of each other. This ability allows host mapper to gain all the
|
69
|
+
mappings of the mounted mapper, thus providing more information for external usage (both reading
|
70
|
+
and writing). Usually, target for mounted mapper may be obtained from association of target of
|
71
|
+
the host mapper itself, but may be defined manually.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
class CustomerMapper < FlatMap::Mapper
|
75
|
+
map :first_name, :last_name
|
76
|
+
end
|
77
|
+
class CustomerAccountMapper < FlatMap::Mapper
|
78
|
+
map :source, :brand, :format => :enum
|
79
|
+
mount :customer
|
80
|
+
end
|
81
|
+
mapper = CustomerAccountMapper.find(1)
|
82
|
+
mapper.read # => {:first_name => 'John', :last_name => 'Smith', :source => nil, :brand => 'FTW'}
|
83
|
+
mapper.write(params) # Will assign params for both CustomerAccount and Customer records
|
84
|
+
```
|
85
|
+
|
86
|
+
The following options may be used when mounting a mapper:
|
87
|
+
|
88
|
+
* `:mapper_class` Specifies mapper class if it cannot be determined from mounting itself
|
89
|
+
* `:target` Allows to manually specify target for the new mapper. May be oject or lambda
|
90
|
+
with arity of one that accepts host mapper target as argument. Comes in handy
|
91
|
+
when target cannot be obviously detected or requires additional setup:
|
92
|
+
`mount :title, :target => lambda{ |customer| customer.title_customers.build.build_title }`
|
93
|
+
* `:traits` Specifies list of traits to be used by mounted mapper
|
94
|
+
* `:suffix` Specifies the suffix that will be appended to all mappings and mountings of mapper,
|
95
|
+
as well as mapper name itself.
|
96
|
+
|
97
|
+
### Traits
|
98
|
+
|
99
|
+
Traits allow mappers to encapsulate named sets of additional definitions, and use them optionally
|
100
|
+
on mapper initialization. Everything that can be defined within the mapper may be defined within
|
101
|
+
the trait. In fact, from the implementation perspective traits are mappers themselves that are
|
102
|
+
mounted on the host mapper.
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
class CustomerAccountMapper < FlatMap::Mapper
|
106
|
+
map :brand, :format => :enum
|
107
|
+
trait :with_email do
|
108
|
+
map :source, :format => :enum
|
109
|
+
mount :email_address
|
110
|
+
trait :with_email_phones_residence do
|
111
|
+
mount :customer, :traits => [:with_phone_numbers, :with_residence]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
CustomerAccountMapper.find(1).read # => {:brand => 'TLP'}
|
116
|
+
CustomerAccountMapper.find(1, :with_email).read # => {:brand => 'TLP', :source => nil, :email_address => 'j.smith@gmail.com'}
|
117
|
+
CustomerAccountMapper.find(1, :with_email_phone_residence).read # => :brand, :source, :email_address, phone numbers,
|
118
|
+
#:residence attributes - all will be available for reading and writing in plain hash
|
119
|
+
```
|
120
|
+
|
121
|
+
### Extensions
|
122
|
+
|
123
|
+
When mounting a mapper, one can pass an optional block. This block is used as an extension for a mounted
|
124
|
+
mapper and acts as an anonymous trait. For example:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
class CustomerAccountMapper < FlatMap::Mapper
|
128
|
+
mount :customer do
|
129
|
+
map :dob => :date_of_birth, :format => :i18n_l
|
130
|
+
validates_presence_of :dob
|
131
|
+
|
132
|
+
mount :unique_identifier
|
133
|
+
|
134
|
+
validates_acceptance_of :mandatory_agreement, :message => "You must check this box to continue"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
```
|
138
|
+
|
139
|
+
### Validation
|
140
|
+
|
141
|
+
`FlatMap::Mapper` includes `ActiveModel::Validations` module, allowing each model to
|
142
|
+
perform its own validation routines before trying to save its target (which is usually AR model). Mapper
|
143
|
+
validation is very handy when mappers are used with Rails forms, since there no need to lookup for a
|
144
|
+
deeply nested errors hash of the AR models to extract error messages. Mapper validations will attach
|
145
|
+
messages to mapping names.
|
146
|
+
Mapper validations become even more useful when used within traits, providing way of very flexible validation sets.
|
147
|
+
|
148
|
+
### Callbacks
|
149
|
+
|
150
|
+
Since mappers include `ActiveModel::Validation`, they already support ActiveSupport's callbacks.
|
151
|
+
Additionally, `:save` callbacks have been defined (i.e. there have been define_callbacks `:save`
|
152
|
+
call for `FlatMap::Mapper`). This allows you to control flow of mapper saving:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
set_callback :save, :before, :set_model_validation
|
156
|
+
def set_model_validation
|
157
|
+
target.use_validation :some_themis_validation
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
### Skipping
|
162
|
+
|
163
|
+
In some cases, it is required to omit mapper processing after it has been created within mounting chain. If
|
164
|
+
`skip!` method is called on mapper, it will return `true` for `valid?` and `save`
|
165
|
+
method calls without performing any other operations. For example:
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
class CustomerMapper < FlatMap::Mapper
|
169
|
+
# some definitions
|
170
|
+
|
171
|
+
trait :product_selection do
|
172
|
+
attr_reader :selected_product_id
|
173
|
+
|
174
|
+
mount :product
|
175
|
+
|
176
|
+
set_callback :validate, :before, :ignore_new_product
|
177
|
+
|
178
|
+
def ignore_new_product
|
179
|
+
mounting(:product).skip! if product_selected?
|
180
|
+
end
|
181
|
+
|
182
|
+
# some more definitions
|
183
|
+
end
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
187
|
+
### Attribute Methods
|
188
|
+
|
189
|
+
All mappers have the ability to read and write values via method calls:
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
mapper.read[:first_name] # => John
|
193
|
+
mapper.first_name # => 'John'
|
194
|
+
mapper.last_name = 'Smith'
|
195
|
+
```
|
196
|
+
|
197
|
+
## Run tests
|
198
|
+
|
199
|
+
```sh
|
200
|
+
rake spec
|
201
|
+
```
|
202
|
+
|
203
|
+
## Credits
|
204
|
+
|
205
|
+
* [Artem Kuzko](https://github.com/akuzko)
|
206
|
+
* [Zachary Belzer](https://github.com/zbelzer)
|
207
|
+
* [Potapov Sergey](https://github.com/greyblake)
|
208
|
+
|
209
|
+
## Copyright
|
210
|
+
|
211
|
+
Copyright (c) 2013 TMX Credit.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
task :default => :spec
|
5
|
+
RSpec::Core::RakeTask.new
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
Rake::RDocTask.new do |rdoc|
|
9
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
10
|
+
|
11
|
+
rdoc.rdoc_dir = 'rdoc'
|
12
|
+
rdoc.title = "flat_map #{version}"
|
13
|
+
rdoc.rdoc_files.include('README*')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
data/flat_map.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "flat_map/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "flat_map"
|
7
|
+
s.version = FlatMap::VERSION
|
8
|
+
s.authors = ["TMX Credit", "Artem Kuzko", "Zachary Belzer", "Sergey Potapov"]
|
9
|
+
s.email = ["rubygems@tmxcredit.com", "a.kuzko@gmail.com", "zbelzer@gmail.com", "blake131313@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/TMXCredit/flat_map"
|
11
|
+
s.licenses = ["LICENSE"]
|
12
|
+
s.summary = %q{Deep object graph to a plain properties mapper}
|
13
|
+
s.description = %q{This library allows to map accessors and properties of deeply
|
14
|
+
nested object graph to a plain mapper object with flexible behavior}
|
15
|
+
|
16
|
+
s.rubyforge_project = "flat_map"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
# specify any dependencies here; for example:
|
24
|
+
s.add_dependency(%q<activesupport>, ["~> 3.2"])
|
25
|
+
s.add_dependency(%q<activerecord>, ["~> 3.2"])
|
26
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
27
|
+
|
28
|
+
s.add_development_dependency "rspec"
|
29
|
+
s.add_development_dependency "rake"
|
30
|
+
end
|
data/lib/flat_map.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
module FlatMap
|
2
|
+
# +BaseMapper+ is an abstract class that hosts overwhelming majority
|
3
|
+
# of common functionality of {EmptyMapper EmptyMappers} and {Mapper Mappers}.
|
4
|
+
#
|
5
|
+
# For more detailed information on what mappers are, refer to {Mapper} documentation.
|
6
|
+
class BaseMapper
|
7
|
+
extend ActiveSupport::Autoload
|
8
|
+
|
9
|
+
autoload :Mapping
|
10
|
+
autoload :Mounting
|
11
|
+
autoload :Traits
|
12
|
+
autoload :Factory
|
13
|
+
autoload :AttributeMethods
|
14
|
+
autoload :Persistence
|
15
|
+
autoload :Skipping
|
16
|
+
|
17
|
+
include Mapping
|
18
|
+
include Mounting
|
19
|
+
include Traits
|
20
|
+
include AttributeMethods
|
21
|
+
include ActiveModel::Validations
|
22
|
+
include Persistence
|
23
|
+
include Skipping
|
24
|
+
|
25
|
+
attr_reader :traits
|
26
|
+
attr_writer :host, :suffix
|
27
|
+
attr_accessor :owner, :name
|
28
|
+
|
29
|
+
# Callback to dup mappings and mountings on inheritance.
|
30
|
+
# The values are cloned from actual mappers (i.e. something
|
31
|
+
# like CustomerAccountMapper, since it is useless to clone
|
32
|
+
# empty values of FlatMap::Mapper).
|
33
|
+
#
|
34
|
+
# Note: those class attributes are defined in {Mapping}
|
35
|
+
# and {Mounting} modules.
|
36
|
+
def self.inherited(subclass)
|
37
|
+
subclass.mappings = mappings.dup
|
38
|
+
subclass.mountings = mountings.dup
|
39
|
+
end
|
40
|
+
|
41
|
+
# Raise exception on trying to initialize an instance.
|
42
|
+
#
|
43
|
+
# @raise [RuntimeError]
|
44
|
+
def initialize
|
45
|
+
raise 'BaseMapper is abstract class and cannot be initialized'
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return a simple string representation of +mapper+. Done so to
|
49
|
+
# avoid really long inspection of internal objects (target -
|
50
|
+
# usually AR model, mountings and mappings)
|
51
|
+
# @return [String]
|
52
|
+
def inspect
|
53
|
+
to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return +true+ if +mapper+ is owned. This means that current
|
57
|
+
# mapper is actually a trait. Thus, it is a part of an owner
|
58
|
+
# mapper.
|
59
|
+
#
|
60
|
+
# @return [Boolean]
|
61
|
+
def owned?
|
62
|
+
owner.present?
|
63
|
+
end
|
64
|
+
|
65
|
+
# If mapper was mounted by another mapper, host is the one who
|
66
|
+
# mounted +self+.
|
67
|
+
#
|
68
|
+
# @return [FlatMap::Mapper]
|
69
|
+
def host
|
70
|
+
owned? ? owner.host : @host
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return +true+ if mapper is hosted, i.e. it is mounted by another
|
74
|
+
# mapper.
|
75
|
+
#
|
76
|
+
# @return [Boolean]
|
77
|
+
def hosted?
|
78
|
+
host.present?
|
79
|
+
end
|
80
|
+
|
81
|
+
# +suffix+ reader. Delegated to owner for owned mappers.
|
82
|
+
#
|
83
|
+
# @return [String, nil]
|
84
|
+
def suffix
|
85
|
+
owned? ? owner.suffix : @suffix
|
86
|
+
end
|
87
|
+
|
88
|
+
# Return +true+ if +suffix+ is present.
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
def suffixed?
|
92
|
+
suffix.present?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|