flatter-extensions 0.1.1 → 0.2.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/README.md +15 -16
- data/flatter-extensions.gemspec +1 -1
- data/lib/flatter/extensions/active_record.rb +93 -106
- data/lib/flatter/extensions/multiparam.rb +5 -3
- data/lib/flatter/extensions/skipping.rb +1 -0
- data/lib/flatter/extensions/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1610548722ed156df3b6ec87c309f3932bb4cf5
|
4
|
+
data.tar.gz: 3babab0a77a55252c362bb0f1652cb77131264b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b247e946523b399435929d1e8da0a198a249cc1ca8877ddfa60ee10c269c4ee73890f20e4b78f8a9af5eb7a0145c6b6b822187fef1fe285fe91b1293ced345c4
|
7
|
+
data.tar.gz: bd68d670ccb3c43c2a6222e353028e5f9047b197128efd193145f5c304cd486af2c2c068620d3fc56ece75a6e875b8e15965c48851c3486a28f0603b0281d4d0
|
data/README.md
CHANGED
@@ -153,19 +153,6 @@ single mapper object with plain hash of attributes that can be used to render a
|
|
153
153
|
used as a form object itself to distribute form params among records, or used in
|
154
154
|
your API, encapsulating processing logic with reusable traits.
|
155
155
|
|
156
|
-
`:active_record` extension depends on `:skipping` extension to be able to utilize
|
157
|
-
it properly. This means that if you use `:active_record` extension, `:skipping`
|
158
|
-
will be used automatically. Although there will be no harm using it explicitly
|
159
|
-
like:
|
160
|
-
|
161
|
-
```ruby
|
162
|
-
Flatten.configure do |f|
|
163
|
-
f.use :order
|
164
|
-
f.use :skipping
|
165
|
-
f.use :active_record
|
166
|
-
end
|
167
|
-
```
|
168
|
-
|
169
156
|
When using `:active_record` extension, you should keep in mind following things:
|
170
157
|
|
171
158
|
#### Mounted target from association
|
@@ -177,26 +164,38 @@ will be tried to be derived from relevant association. For example:
|
|
177
164
|
class Person < ActiveRecord::Base
|
178
165
|
belongs_to :user
|
179
166
|
has_one :location
|
167
|
+
has_many :notes
|
180
168
|
has_many :phones
|
181
169
|
end
|
182
170
|
|
183
171
|
class PersonMapper < Flatter::Mapper
|
184
172
|
mount :user
|
185
173
|
mount :location
|
186
|
-
mount :
|
174
|
+
mount :note
|
175
|
+
mount :phones
|
187
176
|
end
|
188
177
|
```
|
189
178
|
|
190
179
|
Here we have:
|
191
180
|
- `:user` is a `:belongs_to` association. Target for mounted `UserMapper` will
|
192
181
|
be by default fetched as `person.user || person.build_user`.
|
182
|
+
|
193
183
|
- `:location` is a `:has_one` association. Just like `:user`, target for mounted
|
194
184
|
`LocationMapper` will be fetched as `person.location || person.build_location`.
|
195
|
-
|
196
|
-
|
185
|
+
|
186
|
+
- `:notes` is a `:has_many` association, and we map **singular** note. In this
|
187
|
+
case target for `PhoneMapper` is fetched as `person.notes.build`. Thus, you may
|
197
188
|
want to `skip!` this mounting before save or validation to prevent creating
|
198
189
|
freshly-built record, if it was not populated with any values.
|
199
190
|
|
191
|
+
- `:phones` is a `:has_many` association, mounted as a collection mountings `:phones`.
|
192
|
+
In this case whole association would handled by mapper as a collection (this
|
193
|
+
feature is available starting from `0.2.0` version of `flatter`). Thus, reading
|
194
|
+
instance of `PersonMapper` will give you array of `phones`, each of which will
|
195
|
+
have it's own `key` value dependent on it's definition. See
|
196
|
+
[flatter Collections](https://github.com/akuzko/flatter#collections) for more
|
197
|
+
details on how mapped collections are handled.
|
198
|
+
|
200
199
|
Mounting collection associations and working with them as with collections is
|
201
200
|
not supported for now.
|
202
201
|
|
data/flatter-extensions.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
-
spec.add_dependency "flatter"
|
27
|
+
spec.add_dependency "flatter", "~> 0.2"
|
28
28
|
|
29
29
|
spec.add_development_dependency "activerecord", ">= 4.0"
|
30
30
|
spec.add_development_dependency "sqlite3"
|
@@ -1,143 +1,130 @@
|
|
1
|
-
|
2
|
-
module
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
1
|
+
module Flatter
|
2
|
+
module Extensions
|
3
|
+
module ActiveRecord
|
4
|
+
extend ::Flatter::Extension
|
5
|
+
|
6
|
+
module SkipCallbacks
|
7
|
+
def save_without_callbacks
|
8
|
+
@_saving_without_callbacks = true
|
9
|
+
create_or_update
|
10
|
+
ensure
|
11
|
+
remove_instance_variable('@_saving_without_callbacks')
|
12
|
+
end
|
14
13
|
|
15
|
-
|
14
|
+
private
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def _run_create_callbacks
|
22
|
-
@_saving_without_callbacks ? yield : super
|
23
|
-
end
|
16
|
+
def _run_save_callbacks
|
17
|
+
@_saving_without_callbacks ? yield : super
|
18
|
+
end
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
end
|
20
|
+
def _run_create_callbacks
|
21
|
+
@_saving_without_callbacks ? yield : super
|
28
22
|
end
|
29
23
|
|
30
|
-
|
24
|
+
def _run_update_callbacks
|
25
|
+
@_saving_without_callbacks ? yield : super
|
26
|
+
end
|
27
|
+
end
|
31
28
|
|
32
|
-
|
29
|
+
register_as :active_record
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
hooked do
|
32
|
+
::ActiveRecord::Base.send(:prepend, SkipCallbacks)
|
33
|
+
end
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
factory.extend do
|
36
|
+
def default_target_from(mapper)
|
37
|
+
return super unless mapper.ar?
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
target_from_association(mapper.target) || super
|
40
|
+
end
|
41
|
+
private :default_target_from
|
45
42
|
|
46
|
-
|
47
|
-
|
43
|
+
def target_from_association(target)
|
44
|
+
reflection = reflection_from_target(target)
|
48
45
|
|
49
|
-
|
46
|
+
return unless reflection.present?
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
48
|
+
case reflection.macro
|
49
|
+
when :has_one, :belongs_to
|
50
|
+
target.public_send(name) || target.public_send("build_#{name}")
|
51
|
+
when :has_many
|
52
|
+
association = target.association(reflection.name)
|
53
|
+
collection? ? association.load_target : association.build
|
57
54
|
end
|
58
|
-
|
55
|
+
end
|
56
|
+
private :target_from_association
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
private :reflection_from_target
|
58
|
+
def reflection_from_target(target)
|
59
|
+
target_class = target.class
|
60
|
+
reflection = target_class.reflect_on_association(name.to_sym)
|
61
|
+
reflection || target_class.reflect_on_association(name.pluralize.to_sym)
|
66
62
|
end
|
63
|
+
private :reflection_from_target
|
64
|
+
end
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
mapper.add_options :foreign_key, :mounter_foreign_key do
|
67
|
+
def apply(*)
|
68
|
+
return super unless ar?
|
71
69
|
|
72
|
-
|
73
|
-
|
74
|
-
end
|
70
|
+
!!::ActiveRecord::Base.transaction do
|
71
|
+
super or raise ::ActiveRecord::Rollback
|
75
72
|
end
|
73
|
+
end
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
75
|
+
def save
|
76
|
+
!!::ActiveRecord::Base.transaction do
|
77
|
+
begin
|
78
|
+
super
|
79
|
+
rescue ::ActiveRecord::StatementInvalid
|
80
|
+
raise ::ActiveRecord::Rollback
|
84
81
|
end
|
85
82
|
end
|
83
|
+
end
|
86
84
|
|
87
|
-
|
88
|
-
|
85
|
+
def delete_target_item(item)
|
86
|
+
item.destroy! && super
|
87
|
+
end
|
89
88
|
|
90
|
-
|
89
|
+
def save_target
|
90
|
+
return super unless ar?
|
91
91
|
|
92
|
-
|
93
|
-
result = target.save_without_callbacks
|
92
|
+
assign_foreign_keys_from_mountings
|
94
93
|
|
95
|
-
|
96
|
-
assign_foreign_keys_for_mountings
|
97
|
-
end
|
94
|
+
result = target.save_without_callbacks
|
98
95
|
|
99
|
-
|
100
|
-
end
|
101
|
-
protected :save_target
|
96
|
+
assign_foreign_keys_for_mountings if result
|
102
97
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
end
|
108
|
-
private :assign_foreign_keys_from_mountings
|
98
|
+
result != false
|
99
|
+
end
|
100
|
+
protected :save_target
|
109
101
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
end
|
102
|
+
def assign_foreign_keys_from_mountings
|
103
|
+
associated_mountings(:mounter_foreign_key).each do |mounting|
|
104
|
+
target[mounting.mounter_foreign_key] = mounting.target.id
|
114
105
|
end
|
115
|
-
|
106
|
+
end
|
107
|
+
private :assign_foreign_keys_from_mountings
|
116
108
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
mounter = mounter.mounter if mounter.trait?
|
121
|
-
mounting.options.key?(key) && mounter == self
|
122
|
-
end
|
123
|
-
end
|
124
|
-
private :associated_mountings
|
125
|
-
|
126
|
-
def skip!
|
127
|
-
if ar?
|
128
|
-
if target.new_record?
|
129
|
-
target.instance_variable_set('@destroyed', true)
|
130
|
-
else
|
131
|
-
target.restore_attributes
|
132
|
-
end
|
133
|
-
end
|
134
|
-
super
|
109
|
+
def assign_foreign_keys_for_mountings
|
110
|
+
associated_mountings(:foreign_key).each do |mounting|
|
111
|
+
mounting.target[mounting.foreign_key] = target.id
|
135
112
|
end
|
113
|
+
end
|
114
|
+
private :assign_foreign_keys_for_mountings
|
136
115
|
|
137
|
-
|
138
|
-
|
116
|
+
def associated_mountings(key)
|
117
|
+
root_mountings.select do |mounting|
|
118
|
+
mounter = mounting.mounter
|
119
|
+
mounter = mounter.mounter if mounter.trait?
|
120
|
+
mounting.options.key?(key) && mounter == self
|
139
121
|
end
|
140
122
|
end
|
123
|
+
private :associated_mountings
|
124
|
+
|
125
|
+
def ar?
|
126
|
+
target.class < ::ActiveRecord::Base
|
127
|
+
end
|
141
128
|
end
|
142
129
|
end
|
143
130
|
end
|
@@ -21,11 +21,13 @@ module Flatter
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def extract_multiparams!(params)
|
24
|
-
|
24
|
+
return super if collection?
|
25
|
+
|
26
|
+
local_mappings.each do |mapping|
|
25
27
|
next unless mapping.multiparam?
|
26
28
|
|
27
29
|
param_keys = params.keys.
|
28
|
-
select{ |key| key.to_s =~ /#{name}\(\d+[if]\)/ }.
|
30
|
+
select{ |key| key.to_s =~ /#{mapping.name}\(\d+[if]\)/ }.
|
29
31
|
sort_by{ |key| key.to_s[/\((\d+).*\)/, 1].to_i }
|
30
32
|
|
31
33
|
next if param_keys.empty?
|
@@ -41,7 +43,7 @@ module Flatter
|
|
41
43
|
values.push value
|
42
44
|
end
|
43
45
|
|
44
|
-
params[name] = args
|
46
|
+
params[mapping.name] = args
|
45
47
|
end
|
46
48
|
end
|
47
49
|
private :extract_multiparams!
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flatter-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artem Kuzko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: flatter
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '0.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '0.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|