acts_as_table 0.0.1
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 +7 -0
- data/.yardopts +1 -0
- data/LICENSE +30 -0
- data/README.md +256 -0
- data/Rakefile +13 -0
- data/app/models/acts_as_table/belongs_to.rb +81 -0
- data/app/models/acts_as_table/column_model.rb +89 -0
- data/app/models/acts_as_table/foreign_key.rb +299 -0
- data/app/models/acts_as_table/foreign_key_map.rb +121 -0
- data/app/models/acts_as_table/has_many.rb +90 -0
- data/app/models/acts_as_table/has_many_target.rb +40 -0
- data/app/models/acts_as_table/lense.rb +131 -0
- data/app/models/acts_as_table/primary_key.rb +108 -0
- data/app/models/acts_as_table/record.rb +109 -0
- data/app/models/acts_as_table/record_error.rb +50 -0
- data/app/models/acts_as_table/record_model.rb +194 -0
- data/app/models/acts_as_table/row_model.rb +285 -0
- data/app/models/acts_as_table/table.rb +41 -0
- data/app/models/acts_as_table/value.rb +80 -0
- data/app/models/concerns/acts_as_table/record_model_class_methods.rb +554 -0
- data/app/models/concerns/acts_as_table/value_provider.rb +223 -0
- data/app/models/concerns/acts_as_table/value_provider_association_methods.rb +57 -0
- data/config/locales/en.yml +8 -0
- data/db/migrate/1_acts_as_table_migration.rb +186 -0
- data/lib/acts_as_table.rb +288 -0
- data/lib/acts_as_table/adapter.rb +81 -0
- data/lib/acts_as_table/engine.rb +14 -0
- data/lib/acts_as_table/headers.rb +196 -0
- data/lib/acts_as_table/mapper.rb +464 -0
- data/lib/acts_as_table/path.rb +157 -0
- data/lib/acts_as_table/reader.rb +149 -0
- data/lib/acts_as_table/version.rb +4 -0
- data/lib/acts_as_table/writer.rb +116 -0
- metadata +181 -0
@@ -0,0 +1,464 @@
|
|
1
|
+
module ActsAsTable
|
2
|
+
# ActsAsTable mapper.
|
3
|
+
module Mapper
|
4
|
+
# ActsAsTable mapper object (abstract).
|
5
|
+
class Base
|
6
|
+
# Returns a new ActsAsTable mapper object.
|
7
|
+
#
|
8
|
+
# @yieldparam [ActsAsTable::Mapper::Base] base
|
9
|
+
# @yieldreturn [void]
|
10
|
+
# @return [ActsAsTable::Mapper::Base]
|
11
|
+
def initialize(&block)
|
12
|
+
if block_given?
|
13
|
+
case block.arity
|
14
|
+
when 1 then block.call(self)
|
15
|
+
else self.instance_eval(&block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::BelongsTo} class for the `:belongs_to` macro.
|
22
|
+
class BelongsTo < Base
|
23
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::BelongsTo} class for the `:belongs_to` macro.
|
24
|
+
#
|
25
|
+
# @param [ActsAsTable::RowModel] row_model
|
26
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
27
|
+
# @param [ActsAsTable::RecordModel] record_model
|
28
|
+
# @param [#to_s] method_name
|
29
|
+
# @param [ActsAsTable::Mapper::RecordModel] target
|
30
|
+
# @yieldparam [ActsAsTable::Mapper::BelongsTo] belongs_to
|
31
|
+
# @yieldreturn [void]
|
32
|
+
# @return [ActsAsTable::Mapper::BelongsTo]
|
33
|
+
def initialize(row_model, column_model_by_key, record_model, method_name, target, &block)
|
34
|
+
@row_model, @column_model_by_key, @record_model = row_model, column_model_by_key, record_model
|
35
|
+
|
36
|
+
@row_model.belongs_tos.build(macro: 'belongs_to', method_name: method_name) do |belongs_to|
|
37
|
+
belongs_to.source_record_model = @record_model
|
38
|
+
|
39
|
+
belongs_to.target_record_model = target.send(:instance_variable_get, :@record_model)
|
40
|
+
end
|
41
|
+
|
42
|
+
super(&block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::ForeignKey} class.
|
47
|
+
class ForeignKey < Base
|
48
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::ForeignKey} class.
|
49
|
+
#
|
50
|
+
# @param [ActsAsTable::RowModel] row_model
|
51
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
52
|
+
# @param [ActsAsTable::RecordModel] record_model
|
53
|
+
# @param [#to_s] method_name
|
54
|
+
# @param [Integer, Symbol, nil] position_or_key
|
55
|
+
# @param [Hash<Symbol, Object>] options
|
56
|
+
# @option options [Boolean] :default
|
57
|
+
# @option options [#to_s] :primary_key
|
58
|
+
# @yieldparam [ActsAsTable::Mapper::ForeignKey] foreign_key
|
59
|
+
# @yieldreturn [void]
|
60
|
+
# @return [ActsAsTable::Mapper::ForeignKey]
|
61
|
+
def initialize(row_model, column_model_by_key, record_model, method_name, position_or_key = nil, **options, &block)
|
62
|
+
options.assert_valid_keys(:default, :primary_key)
|
63
|
+
|
64
|
+
@row_model, @column_model_by_key, @record_model = row_model, column_model_by_key, record_model
|
65
|
+
|
66
|
+
@foreign_key = @record_model.foreign_keys.build(method_name: method_name, primary_key: options[:primary_key] || 'id', default_value: options[:default]) do |foreign_key|
|
67
|
+
unless position_or_key.nil?
|
68
|
+
foreign_key.column_model = position_or_key.is_a?(::Symbol) ? @column_model_by_key[position_or_key] : @row_model.column_models[position_or_key - 1]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
super(&block)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Builds a new instance of the {ActsAsTable::ForeignKeyMap} class.
|
76
|
+
#
|
77
|
+
# @note Target values for regular expressions may refer to capture groups.
|
78
|
+
#
|
79
|
+
# @param [String, Regexp] from
|
80
|
+
# @param [Hash<Symbol, Object>] options
|
81
|
+
# @option options [String] to
|
82
|
+
# @return [ActsAsTable::Mapper::ForeignKey]
|
83
|
+
#
|
84
|
+
# @example Map from a string to another string.
|
85
|
+
# map 'source', to: 'target'
|
86
|
+
#
|
87
|
+
# @example Map from a regular expression to a capture group.
|
88
|
+
# map /City:\s+(.+)/i, to: '\1'
|
89
|
+
#
|
90
|
+
def map(from, **options)
|
91
|
+
options.assert_valid_keys(:to)
|
92
|
+
|
93
|
+
@foreign_key.foreign_key_maps.build({
|
94
|
+
source_value: from.is_a?(::Regexp) ? from.source : from.to_s,
|
95
|
+
target_value: options[:to].to_s,
|
96
|
+
regexp: from.is_a?(::Regexp),
|
97
|
+
extended: from.is_a?(::Regexp) && ((from.options & ::Regexp::EXTENDED) != 0),
|
98
|
+
ignore_case: from.is_a?(::Regexp) && ((from.options & ::Regexp::IGNORECASE) != 0),
|
99
|
+
multiline: from.is_a?(::Regexp) && ((from.options & ::Regexp::MULTILINE) != 0),
|
100
|
+
})
|
101
|
+
|
102
|
+
self
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::HasMany} class for the `:has_and_belongs_to_many` macro.
|
107
|
+
class HasAndBelongsToMany < Base
|
108
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::HasMany} class for the `:has_and_belongs_to_many` macro.
|
109
|
+
#
|
110
|
+
# @param [ActsAsTable::RowModel] row_model
|
111
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
112
|
+
# @param [ActsAsTable::RecordModel] record_model
|
113
|
+
# @param [#to_s] method_name
|
114
|
+
# @param [Array<ActsAsTable::Mapper::RecordModel>] targets
|
115
|
+
# @yieldparam [ActsAsTable::Mapper::HasAndBelongsToMany] has_and_belongs_to_many
|
116
|
+
# @yieldreturn [void]
|
117
|
+
# @return [ActsAsTable::Mapper::HasAndBelongsToMany]
|
118
|
+
def initialize(row_model, column_model_by_key, record_model, method_name, *targets, &block)
|
119
|
+
@row_model, @column_model_by_key, @record_model = row_model, column_model_by_key, record_model
|
120
|
+
|
121
|
+
@row_model.has_manies.build(macro: 'has_and_belongs_to_many', method_name: method_name) do |has_many|
|
122
|
+
has_many.source_record_model = @record_model
|
123
|
+
|
124
|
+
targets.each_with_index do |target, index|
|
125
|
+
has_many.has_many_targets.build(position: index + 1) do |has_many_target|
|
126
|
+
has_many_target.record_model = target.send(:instance_variable_get, :@record_model)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
super(&block)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::HasMany} class for the `:has_many` macro.
|
136
|
+
class HasMany < Base
|
137
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::HasMany} class for the `:has_many` macro.
|
138
|
+
#
|
139
|
+
# @param [ActsAsTable::RowModel] row_model
|
140
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
141
|
+
# @param [ActsAsTable::RecordModel] record_model
|
142
|
+
# @param [#to_s] method_name
|
143
|
+
# @param [Array<ActsAsTable::Mapper::RecordModel>] targets
|
144
|
+
# @yieldparam [ActsAsTable::Mapper::HasMany] has_many
|
145
|
+
# @yieldreturn [void]
|
146
|
+
# @return [ActsAsTable::Mapper::HasMany]
|
147
|
+
def initialize(row_model, column_model_by_key, record_model, method_name, *targets, &block)
|
148
|
+
@row_model, @column_model_by_key, @record_model = row_model, column_model_by_key, record_model
|
149
|
+
|
150
|
+
@row_model.has_manies.build(macro: 'has_many', method_name: method_name) do |has_many|
|
151
|
+
has_many.source_record_model = @record_model
|
152
|
+
|
153
|
+
targets.each_with_index do |target, index|
|
154
|
+
has_many.has_many_targets.build(position: index + 1) do |has_many_target|
|
155
|
+
has_many_target.record_model = target.send(:instance_variable_get, :@record_model)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
super(&block)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::BelongsTo} class for the `:has_one` macro.
|
165
|
+
class HasOne < Base
|
166
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::BelongsTo} class for the `:has_one` macro.
|
167
|
+
#
|
168
|
+
# @param [ActsAsTable::RowModel] row_model
|
169
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
170
|
+
# @param [ActsAsTable::RecordModel] record_model
|
171
|
+
# @param [#to_s] method_name
|
172
|
+
# @param [ActsAsTable::Mapper::RecordModel] target
|
173
|
+
# @yieldparam [ActsAsTable::Mapper::HasOne] has_one
|
174
|
+
# @yieldreturn [void]
|
175
|
+
# @return [ActsAsTable::Mapper::HasOne]
|
176
|
+
def initialize(row_model, column_model_by_key, record_model, method_name, target, &block)
|
177
|
+
@row_model, @column_model_by_key, @record_model = row_model, column_model_by_key, record_model
|
178
|
+
|
179
|
+
@row_model.belongs_tos.build(macro: 'has_one', method_name: method_name) do |belongs_to|
|
180
|
+
belongs_to.source_record_model = @record_model
|
181
|
+
|
182
|
+
belongs_to.target_record_model = target.send(:instance_variable_get, :@record_model)
|
183
|
+
end
|
184
|
+
|
185
|
+
super(&block)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::Lense} class.
|
190
|
+
class Lense < Base
|
191
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::Lense} class.
|
192
|
+
#
|
193
|
+
# @param [ActsAsTable::RowModel] row_model
|
194
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
195
|
+
# @param [ActsAsTable::RecordModel] record_model
|
196
|
+
# @param [#to_s] method_name
|
197
|
+
# @param [Integer, Symbol, nil] position_or_key
|
198
|
+
# @param [Hash<Symbol, Object>] options
|
199
|
+
# @option options [Boolean] :default
|
200
|
+
# @option options [#to_s] :primary_key
|
201
|
+
# @yieldparam [ActsAsTable::Mapper::Lense] lense
|
202
|
+
# @yieldreturn [void]
|
203
|
+
# @return [ActsAsTable::Mapper::Lense]
|
204
|
+
def initialize(row_model, column_model_by_key, record_model, method_name, position_or_key = nil, **options, &block)
|
205
|
+
options.assert_valid_keys(:default)
|
206
|
+
|
207
|
+
@row_model, @column_model_by_key, @record_model = row_model, column_model_by_key, record_model
|
208
|
+
|
209
|
+
@record_model.lenses.build(method_name: method_name, default_value: options[:default]) do |lens|
|
210
|
+
unless position_or_key.nil?
|
211
|
+
lens.column_model = position_or_key.is_a?(::Symbol) ? @column_model_by_key[position_or_key] : @row_model.column_models[position_or_key - 1]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
super(&block)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::PrimaryKey} class.
|
220
|
+
class PrimaryKey < Base
|
221
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::PrimaryKey} class.
|
222
|
+
#
|
223
|
+
# @param [ActsAsTable::RowModel] row_model
|
224
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
225
|
+
# @param [ActsAsTable::RecordModel] record_model
|
226
|
+
# @param [Integer, Symbol, nil] position_or_key
|
227
|
+
# @param [#to_s] method_name
|
228
|
+
# @yieldparam [ActsAsTable::Mapper::PrimaryKey] primary_key
|
229
|
+
# @yieldreturn [void]
|
230
|
+
# @return [ActsAsTable::Mapper::PrimaryKey]
|
231
|
+
def initialize(row_model, column_model_by_key, record_model, position_or_key, method_name = 'id', &block)
|
232
|
+
@row_model, @column_model_by_key, @record_model = row_model, column_model_by_key, record_model
|
233
|
+
|
234
|
+
@record_model.primary_keys.build(method_name: method_name) do |primary_key|
|
235
|
+
primary_key.column_model = position_or_key.is_a?(::Symbol) ? @column_model_by_key[position_or_key] : @row_model.column_models[position_or_key - 1]
|
236
|
+
end
|
237
|
+
|
238
|
+
super(&block)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::RecordModel} class.
|
243
|
+
#
|
244
|
+
# @!method attribute(method_name, position_or_key = nil, **options, &block)
|
245
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::Lense} class.
|
246
|
+
#
|
247
|
+
# @param [#to_s] method_name
|
248
|
+
# @param [Integer, Symbol, nil] position_or_key
|
249
|
+
# @param [Hash<Symbol, Object>] options
|
250
|
+
# @option options [Boolean] :default
|
251
|
+
# @option options [#to_s] :primary_key
|
252
|
+
# @yieldparam [ActsAsTable::Mapper::Lense] lense
|
253
|
+
# @yieldreturn [void]
|
254
|
+
# @return [ActsAsTable::Mapper::Lense]
|
255
|
+
# @!method belongs_to(method_name, target, &block)
|
256
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::BelongsTo} class for the `:belongs_to` macro.
|
257
|
+
#
|
258
|
+
# @param [#to_s] method_name
|
259
|
+
# @param [ActsAsTable::Mapper::RecordModel] target
|
260
|
+
# @yieldparam [ActsAsTable::Mapper::BelongsTo] belongs_to
|
261
|
+
# @yieldreturn [void]
|
262
|
+
# @return [ActsAsTable::Mapper::BelongsTo]
|
263
|
+
# @!method foreign_key(method_name, position_or_key = nil, **options, &block)
|
264
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::ForeignKey} class.
|
265
|
+
#
|
266
|
+
# @param [#to_s] method_name
|
267
|
+
# @param [Integer, Symbol, nil] position_or_key
|
268
|
+
# @param [Hash<Symbol, Object>] options
|
269
|
+
# @option options [Boolean] :default
|
270
|
+
# @option options [#to_s] :primary_key
|
271
|
+
# @yieldparam [ActsAsTable::Mapper::ForeignKey] foreign_key
|
272
|
+
# @yieldreturn [void]
|
273
|
+
# @return [ActsAsTable::Mapper::ForeignKey]
|
274
|
+
# @!method has_and_belongs_to_many(method_name, *targets, &block)
|
275
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::HasMany} class for the `:has_and_belongs_to_many` macro.
|
276
|
+
#
|
277
|
+
# @param [#to_s] method_name
|
278
|
+
# @param [Array<ActsAsTable::Mapper::RecordModel>] targets
|
279
|
+
# @yieldparam [ActsAsTable::Mapper::HasAndBelongsToMany] has_and_belongs_to_many
|
280
|
+
# @yieldreturn [void]
|
281
|
+
# @return [ActsAsTable::Mapper::HasAndBelongsToMany]
|
282
|
+
# @!method has_many(method_name, *targets, &block)
|
283
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::HasMany} class for the `:has_many` macro.
|
284
|
+
#
|
285
|
+
# @param [#to_s] method_name
|
286
|
+
# @param [Array<ActsAsTable::Mapper::RecordModel>] targets
|
287
|
+
# @yieldparam [ActsAsTable::Mapper::HasMany] has_many
|
288
|
+
# @yieldreturn [void]
|
289
|
+
# @return [ActsAsTable::Mapper::HasMany]
|
290
|
+
# @!method has_one(method_name, target, &block)
|
291
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::BelongsTo} class for the `:has_one` macro.
|
292
|
+
#
|
293
|
+
# @param [#to_s] method_name
|
294
|
+
# @param [ActsAsTable::Mapper::RecordModel] target
|
295
|
+
# @yieldparam [ActsAsTable::Mapper::HasOne] has_one
|
296
|
+
# @yieldreturn [void]
|
297
|
+
# @return [ActsAsTable::Mapper::HasOne]
|
298
|
+
# @!method primary_key(position_or_key = nil, method_name = 'id', &block)
|
299
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::PrimaryKey} class.
|
300
|
+
#
|
301
|
+
# @param [Integer, Symbol, nil] position_or_key
|
302
|
+
# @param [#to_s] method_name
|
303
|
+
# @yieldparam [ActsAsTable::Mapper::PrimaryKey] primary_key
|
304
|
+
# @yieldreturn [void]
|
305
|
+
# @return [ActsAsTable::Mapper::PrimaryKey]
|
306
|
+
class RecordModel < Base
|
307
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::RecordModel} class.
|
308
|
+
#
|
309
|
+
# @param [ActsAsTable::RowModel] row_model
|
310
|
+
# @param [Hash<Symbol, ActsAsTable::ColumnModel>] column_model_by_key
|
311
|
+
# @param [#to_s] class_name
|
312
|
+
# @yieldparam [ActsAsTable::Mapper::RecordModel] record_model
|
313
|
+
# @yieldreturn [void]
|
314
|
+
# @return [ActsAsTable::Mapper::RecordModel]
|
315
|
+
def initialize(row_model, column_model_by_key, class_name, &block)
|
316
|
+
@row_model, @column_model_by_key = row_model, column_model_by_key
|
317
|
+
|
318
|
+
@record_model = row_model.record_models.build(class_name: class_name)
|
319
|
+
|
320
|
+
super(&block)
|
321
|
+
end
|
322
|
+
|
323
|
+
{
|
324
|
+
attribute: :Lense,
|
325
|
+
belongs_to: :BelongsTo,
|
326
|
+
foreign_key: :ForeignKey,
|
327
|
+
has_and_belongs_to_many: :HasAndBelongsToMany,
|
328
|
+
has_many: :HasMany,
|
329
|
+
has_one: :HasOne,
|
330
|
+
primary_key: :PrimaryKey,
|
331
|
+
}.each do |method_name, const_name|
|
332
|
+
define_method(method_name) do |*args, &block|
|
333
|
+
ActsAsTable::Mapper.const_get(const_name).new(@row_model, @column_model_by_key, @record_model, *args, &block)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
# ActsAsTable mapper object for an instance of the {ActsAsTable::RowModel} class.
|
339
|
+
#
|
340
|
+
# @see ActsAsTable::RowModel#draw
|
341
|
+
class RowModel < Base
|
342
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::RowModel} class.
|
343
|
+
#
|
344
|
+
# @param [ActsAsTable::RowModel] row_model
|
345
|
+
# @yieldparam [ActsAsTable::Mapper::RowModel] row_model
|
346
|
+
# @yieldreturn [void]
|
347
|
+
# @return [ActsAsTable::Mapper::RowModel]
|
348
|
+
def initialize(row_model, &block)
|
349
|
+
@row_model, @column_model_by_key = row_model, {}
|
350
|
+
|
351
|
+
super(&block)
|
352
|
+
end
|
353
|
+
|
354
|
+
# Builds new ActsAsTable column models in the scope of this ActsAsTable row model and caches them by key, if given.
|
355
|
+
#
|
356
|
+
# @param [#each_pair, #each, #to_s] object
|
357
|
+
# @return [ActsAsTable::Mapper::RowModel]
|
358
|
+
def columns=(object)
|
359
|
+
# @return [Integer]
|
360
|
+
column_models_count = @row_model.column_models.size
|
361
|
+
|
362
|
+
# @return [void]
|
363
|
+
::Enumerator.new { |enumerator|
|
364
|
+
_dfs(object) { |path|
|
365
|
+
enumerator << path
|
366
|
+
}
|
367
|
+
}.each do |path|
|
368
|
+
# @return [Symbol, nil]
|
369
|
+
key = path[-1].is_a?(::Symbol) ? path.pop : nil
|
370
|
+
|
371
|
+
column_models_count += 1
|
372
|
+
|
373
|
+
# @return [ActsAsTable::ColumnModel]
|
374
|
+
column_model = @row_model.column_models.build(position: column_models_count, **_to_column_model_attributes(path))
|
375
|
+
|
376
|
+
unless key.nil?
|
377
|
+
@column_model_by_key[key] = column_model
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
self
|
382
|
+
end
|
383
|
+
|
384
|
+
# Set the root ActsAsTable record model for this ActsAsTable row model.
|
385
|
+
#
|
386
|
+
# @param [ActsAsTable::Mapper::RecordModel] target
|
387
|
+
# @return [ActsAsTable::Mapper::RowModel]
|
388
|
+
def root_model=(target)
|
389
|
+
@row_model.root_record_model = target.send(:instance_variable_get, :@record_model)
|
390
|
+
|
391
|
+
self
|
392
|
+
end
|
393
|
+
|
394
|
+
# Returns a new ActsAsTable mapper object an instance of the {ActsAsTable::RecordModel} class.
|
395
|
+
#
|
396
|
+
# @param [#to_s] class_name
|
397
|
+
# @yieldparam [ActsAsTable::Mapper::RecordModel] record_model
|
398
|
+
# @yieldreturn [void]
|
399
|
+
# @return [ActsAsTable::Mapper::RecordModel]
|
400
|
+
def model(class_name, &block)
|
401
|
+
ActsAsTable::Mapper::RecordModel.new(@row_model, @column_model_by_key, class_name, &block)
|
402
|
+
end
|
403
|
+
|
404
|
+
private
|
405
|
+
|
406
|
+
# Performs a depth-first search of the given object and yields each path from root to leaf.
|
407
|
+
#
|
408
|
+
# @param [#each_pair, #each, #to_s] object
|
409
|
+
# @param [Array<#to_s>] path
|
410
|
+
# @yieldparam [Array<#to_s>] path
|
411
|
+
# @yieldreturn [void]
|
412
|
+
# @return [void]
|
413
|
+
def _dfs(object, path = [], &block)
|
414
|
+
unless block.nil?
|
415
|
+
if object.respond_to?(:each_pair)
|
416
|
+
object.each_pair do |pair|
|
417
|
+
# @return [Array<#to_s>]
|
418
|
+
key, new_object = *pair
|
419
|
+
|
420
|
+
# @return [Array<#to_s>]
|
421
|
+
new_path = path + [key]
|
422
|
+
|
423
|
+
_dfs(new_object, new_path, &block)
|
424
|
+
end
|
425
|
+
elsif object.respond_to?(:each)
|
426
|
+
object.each do |new_object|
|
427
|
+
_dfs(new_object, path, &block)
|
428
|
+
end
|
429
|
+
else
|
430
|
+
# @return [Array<#to_s>]
|
431
|
+
new_path = path + [object]
|
432
|
+
|
433
|
+
case block.arity
|
434
|
+
when 1 then block.call(new_path)
|
435
|
+
else new_path.instance_exec(&block)
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
return
|
441
|
+
end
|
442
|
+
|
443
|
+
# @return [String]
|
444
|
+
COLUMN_MODEL_SEPARATOR_ = "\t".freeze
|
445
|
+
|
446
|
+
# @return [String]
|
447
|
+
WHITESPACE_PATTERN_ = /\s+/i.freeze
|
448
|
+
|
449
|
+
# @return [String]
|
450
|
+
WHITESPACE_REPLACEMENT_ = ' '.freeze
|
451
|
+
|
452
|
+
# Returns the +ActsAsTable::ColumnModel#attributes+ for the given path.
|
453
|
+
#
|
454
|
+
# @param [Array<#to_s>] path
|
455
|
+
# @return [Hash<Symbol, Object>]
|
456
|
+
def _to_column_model_attributes(path)
|
457
|
+
{
|
458
|
+
name: path.collect(&:to_s).collect(&:strip).collect { |s| s.strip.gsub(WHITESPACE_PATTERN_, WHITESPACE_REPLACEMENT_) }.join(COLUMN_MODEL_SEPARATOR_),
|
459
|
+
separator: COLUMN_MODEL_SEPARATOR_,
|
460
|
+
}
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
end
|