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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a3ccff2224155cdb168ccd7de33cadeacb42d34b
4
- data.tar.gz: 16f61b126dc24a8b68dc04fa8dff925bc2fd6a7b
3
+ metadata.gz: d1610548722ed156df3b6ec87c309f3932bb4cf5
4
+ data.tar.gz: 3babab0a77a55252c362bb0f1652cb77131264b4
5
5
  SHA512:
6
- metadata.gz: a0405d1ce282f152a014365af8c51d26d9f7e18c3f2f8ca5ffac5971e55551e289359a74408f78051e6fbc5f0226092558171c4b8060ad58ca82c95ac11647b7
7
- data.tar.gz: a72f133129b400d4c281a0694278d73c5dabd3c7fbe0bdd924787158c717bf68917131457280de05a880aab24f57e62d1068be6b3d3a0246216c70cd00b6832f
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 :phone
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
- - `:phones` is a `:has_many` association, and we map **singular** phone. In this
196
- case target for `PhoneMapper` is fetched as `person.phones.build`. Thus, you may
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
 
@@ -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
- if defined? ActiveRecord
2
- module Flatter
3
- module Extensions
4
- module ActiveRecord
5
- extend ::Flatter::Extension
6
-
7
- module SkipCallbacks
8
- def save_without_callbacks
9
- @_saving_without_callbacks = true
10
- create_or_update
11
- ensure
12
- remove_instance_variable('@_saving_without_callbacks')
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
- private
14
+ private
16
15
 
17
- def _run_save_callbacks
18
- @_saving_without_callbacks ? yield : super
19
- end
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
- def _run_update_callbacks
26
- @_saving_without_callbacks ? yield : super
27
- end
20
+ def _run_create_callbacks
21
+ @_saving_without_callbacks ? yield : super
28
22
  end
29
23
 
30
- register_as :active_record
24
+ def _run_update_callbacks
25
+ @_saving_without_callbacks ? yield : super
26
+ end
27
+ end
31
28
 
32
- depends_on :skipping
29
+ register_as :active_record
33
30
 
34
- hooked do
35
- ::ActiveRecord::Base.send(:prepend, SkipCallbacks)
36
- end
31
+ hooked do
32
+ ::ActiveRecord::Base.send(:prepend, SkipCallbacks)
33
+ end
37
34
 
38
- factory.extend do
39
- def default_target_from(mapper)
40
- return super unless mapper.ar?
35
+ factory.extend do
36
+ def default_target_from(mapper)
37
+ return super unless mapper.ar?
41
38
 
42
- target_from_association(mapper.target) || super
43
- end
44
- private :default_target_from
39
+ target_from_association(mapper.target) || super
40
+ end
41
+ private :default_target_from
45
42
 
46
- def target_from_association(target)
47
- reflection = reflection_from_target(target)
43
+ def target_from_association(target)
44
+ reflection = reflection_from_target(target)
48
45
 
49
- return unless reflection.present?
46
+ return unless reflection.present?
50
47
 
51
- case reflection.macro
52
- when :has_one, :belongs_to
53
- target.public_send(name) || target.public_send("build_#{name}")
54
- when :has_many
55
- target.association(reflection.name).build
56
- end
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
- private :target_from_association
55
+ end
56
+ private :target_from_association
59
57
 
60
- def reflection_from_target(target)
61
- target_class = target.class
62
- reflection = target_class.reflect_on_association(name.to_sym)
63
- reflection || target_class.reflect_on_association(name.pluralize.to_sym)
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
- mapper.add_options :foreign_key, :mounter_foreign_key do
69
- def apply(*)
70
- return super unless ar?
66
+ mapper.add_options :foreign_key, :mounter_foreign_key do
67
+ def apply(*)
68
+ return super unless ar?
71
69
 
72
- !!::ActiveRecord::Base.transaction do
73
- super or raise ::ActiveRecord::Rollback
74
- end
70
+ !!::ActiveRecord::Base.transaction do
71
+ super or raise ::ActiveRecord::Rollback
75
72
  end
73
+ end
76
74
 
77
- def save
78
- !!::ActiveRecord::Base.transaction do
79
- begin
80
- super
81
- rescue ::ActiveRecord::StatementInvalid
82
- raise ::ActiveRecord::Rollback
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
- def save_target
88
- return super unless ar?
85
+ def delete_target_item(item)
86
+ item.destroy! && super
87
+ end
89
88
 
90
- assign_foreign_keys_from_mountings
89
+ def save_target
90
+ return super unless ar?
91
91
 
92
- was_new = target.new_record?
93
- result = target.save_without_callbacks
92
+ assign_foreign_keys_from_mountings
94
93
 
95
- if result && was_new
96
- assign_foreign_keys_for_mountings
97
- end
94
+ result = target.save_without_callbacks
98
95
 
99
- result != false
100
- end
101
- protected :save_target
96
+ assign_foreign_keys_for_mountings if result
102
97
 
103
- def assign_foreign_keys_from_mountings
104
- associated_mountings(:mounter_foreign_key).each do |mounting|
105
- target[mounting.mounter_foreign_key] = mounting.target.id
106
- end
107
- end
108
- private :assign_foreign_keys_from_mountings
98
+ result != false
99
+ end
100
+ protected :save_target
109
101
 
110
- def assign_foreign_keys_for_mountings
111
- associated_mountings(:foreign_key).each do |mounting|
112
- mounting.target[mounting.foreign_key] = target.id
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
- private :assign_foreign_keys_for_mountings
106
+ end
107
+ private :assign_foreign_keys_from_mountings
116
108
 
117
- def associated_mountings(key)
118
- root_mountings.select do |mounting|
119
- mounter = mounting.mounter
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
- def ar?
138
- target.class < ::ActiveRecord::Base
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
- mappings.each do |name, mapping|
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!
@@ -20,6 +20,7 @@ module Flatter
20
20
  end
21
21
 
22
22
  def skip!
23
+ collection.each(&:skip!) if collection?
23
24
  @skipped = true
24
25
  end
25
26
 
@@ -1,5 +1,5 @@
1
1
  module Flatter
2
2
  module Extensions
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
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.1.1
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-08 00:00:00.000000000 Z
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