jsonapi_compliable 0.8.0 → 0.9.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: 10190f5b7e0cd15456e21552f847b9a41d5fae80
4
- data.tar.gz: 002b8c3ffb2fe962e682182199519a8182a909a0
3
+ metadata.gz: f5fedeea577e5f906c540f5a4204450c98d70055
4
+ data.tar.gz: d38aa664cf50468fab2af7d1761acfa78d54f69c
5
5
  SHA512:
6
- metadata.gz: 5744a2c7eba2af24ea476210cf9804fdbc16d0c636b6e9d55c586e198a6ddf196122f8e6e27029d7f723cd07670efbea3d6aa21d4368ece68152c212249dd0ca
7
- data.tar.gz: dbae4b77df449427b11d0dd5135a722b713a11c8f7fd05d62192dbd13c043ce48fcd3517179fb72afef9a05d460aadc6a4137fda0ef200f1bd1b6f9a99eca2c8
6
+ metadata.gz: e14232a3b4a4e43ef1945f4ca49358dfb537e80803ef96bc24b84b0b56b020036a6090cd1cd4215445c070ba71f14b3149fb5f420ac71ff42be6b23811626abb
7
+ data.tar.gz: 0cdcb246386014a2f65074aa9ece19d97c2b575060ea97b74d740ad707937a8dbc1431f66fb311c6d4193f8083db07a2c384d5e72b647c616db0b015176d5139
@@ -39,9 +39,9 @@ module JsonapiCompliable
39
39
  parent.send(:"#{association_name}=", relevant_child)
40
40
  end
41
41
  end
42
- end
43
42
 
44
- instance_eval(&blk) if blk
43
+ instance_eval(&blk) if blk
44
+ end
45
45
  end
46
46
 
47
47
  def has_one(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, &blk)
@@ -191,6 +191,50 @@ module JsonapiCompliable
191
191
  resource.disassociate(parent, child, association_name, type)
192
192
  end
193
193
 
194
+ HOOK_ACTIONS = [:save, :create, :update, :destroy, :disassociate]
195
+
196
+ # Configure post-processing hooks
197
+ #
198
+ # In particular, helpful for bulk operations. "after_save" will fire
199
+ # for any persistence method - +:create+, +:update+, +:destroy+, +:disassociate+.
200
+ # Use "only" and "except" keyword arguments to fire only for a
201
+ # specific persistence method.
202
+ #
203
+ # @example Bulk Notify Users on Invite
204
+ # class ProjectResource < ApplicationResource
205
+ # # ... code ...
206
+ # allow_sideload :users, resource: UserResource do
207
+ # # scope {}
208
+ # # assign {}
209
+ # after_save only: [:create] do |project, users|
210
+ # UserMailer.invite(project, users).deliver_later
211
+ # end
212
+ # end
213
+ # end
214
+ #
215
+ # @see #hooks
216
+ # @see Util::Persistence
217
+ def after_save(only: [], except: [], &blk)
218
+ actions = HOOK_ACTIONS - except
219
+ actions = only & actions
220
+ actions = [:save] if only.empty? && except.empty?
221
+ actions.each do |a|
222
+ hooks[:"after_#{a}"] << blk
223
+ end
224
+ end
225
+
226
+ # Get the hooks the user has configured
227
+ # @see #after_save
228
+ # @return hash of hooks, ie +{ after_create: #<Proc>}+
229
+ def hooks
230
+ @hooks ||= {}.tap do |h|
231
+ HOOK_ACTIONS.each do |a|
232
+ h[:"after_#{a}"] = []
233
+ h[:"before_#{a}"] = []
234
+ end
235
+ end
236
+ end
237
+
194
238
  # Define an attribute that groups the parent records. For instance, with
195
239
  # an ActiveRecord polymorphic belongs_to there will be a +parent_id+
196
240
  # and +parent_type+. We would want to group on +parent_type+:
@@ -340,6 +384,15 @@ module JsonapiCompliable
340
384
  end
341
385
  end
342
386
 
387
+ def fire_hooks!(parent, objects, method)
388
+ return unless self.hooks
389
+
390
+ hooks = self.hooks[:"after_#{method}"] + self.hooks[:after_save]
391
+ hooks.compact.each do |hook|
392
+ resource.instance_exec(parent, objects, &hook)
393
+ end
394
+ end
395
+
343
396
  private
344
397
 
345
398
  def nested_sideload_hash(sideload, processed)
@@ -27,6 +27,7 @@ class JsonapiCompliable::Util::Persistence
27
27
  # * associate parent objects with current object
28
28
  # * process children
29
29
  # * associate children
30
+ # * run post-process sideload hooks
30
31
  # * return current object
31
32
  #
32
33
  # @return the persisted model instance
@@ -36,14 +37,17 @@ class JsonapiCompliable::Util::Persistence
36
37
 
37
38
  persisted = persist_object(@meta[:method], @attributes)
38
39
  assign_temp_id(persisted, @meta[:temp_id])
40
+
39
41
  associate_parents(persisted, parents)
40
42
 
41
43
  children = process_has_many(@relationships, persisted) do |x|
42
44
  update_foreign_key(persisted, x[:attributes], x)
43
45
  end
44
46
 
45
- associate_children(persisted, children)
46
- persisted unless @meta[:method] == :destroy
47
+ associate_children(persisted, children) unless @meta[:method] == :destroy
48
+ post_process(persisted, parents)
49
+ post_process(persisted, children)
50
+ persisted
47
51
  end
48
52
 
49
53
  private
@@ -76,6 +80,9 @@ class JsonapiCompliable::Util::Persistence
76
80
  end
77
81
 
78
82
  def associate_parents(object, parents)
83
+ # No need to associate to destroyed objects
84
+ parents = parents.select { |x| x[:meta][:method] != :destroy }
85
+
79
86
  parents.each do |x|
80
87
  if x[:object] && object
81
88
  if x[:meta][:method] == :disassociate
@@ -88,6 +95,9 @@ class JsonapiCompliable::Util::Persistence
88
95
  end
89
96
 
90
97
  def associate_children(object, children)
98
+ # No need to associate destroyed objects
99
+ return if @meta[:method] == :destroy
100
+
91
101
  children.each do |x|
92
102
  if x[:object] && object
93
103
  if x[:meta][:method] == :disassociate
@@ -131,6 +141,16 @@ class JsonapiCompliable::Util::Persistence
131
141
  end
132
142
  end
133
143
 
144
+ def post_process(caller_model, processed)
145
+ groups = processed.group_by { |x| x[:meta][:method] }
146
+ groups.each_pair do |method, group|
147
+ group.group_by { |g| g[:sideload] }.each_pair do |sideload, members|
148
+ objects = members.map { |x| x[:object] }
149
+ sideload.fire_hooks!(caller_model, objects, method)
150
+ end
151
+ end
152
+ end
153
+
134
154
  def assign_temp_id(object, temp_id)
135
155
  object.instance_variable_set(:@_jsonapi_temp_id, temp_id)
136
156
  end
@@ -1,3 +1,3 @@
1
1
  module JsonapiCompliable
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_compliable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-08-18 00:00:00.000000000 Z
12
+ date: 2017-09-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: jsonapi-serializable