web-connect 0.3.3 → 0.4.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: 5d4dd9d54db821723fcfae4cd5da92c4cb7f0eae
4
- data.tar.gz: eb61afb0a614d86784037143f03b32fe24a91f12
3
+ metadata.gz: a8bff92c7d13988bc68cf2aa9623c9621624319a
4
+ data.tar.gz: 303b28ea1214ce4c065527f0b5ab1efda2d2268c
5
5
  SHA512:
6
- metadata.gz: e73df512556bf4cfab146473e2fd1029b8c947786b08fd458ee0a1356aeb5fb825635dbe7d9baed871022bb04617cbef0c9f96c731661d56b67b2cfa0875773d
7
- data.tar.gz: eac0ccbf6651b1f03d35a190c02e39f69207f57377aeae70e101c92a8057d8512d4afd6db0396594b56d6fda3bd1e61c91e145e4ad6e5834cb1516dfd8d0e130
6
+ metadata.gz: 7136d9aa509a71ff9d8208e5d463746d4f5d99c5a30ff1718ccd6427e7cbc0c95fc4432bf6f597b647f441d34b2070d77e875c430e635d9da114a506dd6882fb
7
+ data.tar.gz: 4b9672b379f9330b7537c35b88980de3405ac7d5294e3150af2814ac9049b8e9fb02a6f11b117cf533fc9ee6d20f85bc02b9b4d0ff99a46593e8e46077c41a41
@@ -1 +1,2 @@
1
1
  require_relative 'components/octa_word'
2
+ require_relative 'components/hash_of_models'
@@ -0,0 +1,52 @@
1
+ module Netfira::WebConnect
2
+ class HashOfModels < Hash
3
+
4
+ def initialize
5
+ super { |hash, key| hash[key] = [] }
6
+ end
7
+
8
+ def [](key)
9
+ super class_for_key(key)
10
+ end
11
+
12
+ def <<(value)
13
+ raise 'Only models are acceptable' unless Model === value
14
+ self[value.class] << value
15
+ end
16
+
17
+ def method_missing(sym, *args, &block)
18
+ if respond_to_missing? sym
19
+ klass = class_for_key(sym)
20
+ -> { self[klass] }.tap { |method| self.class.__send__ :define_method, sym, method }.call
21
+ else
22
+ super sym, *args, &block
23
+ end
24
+ end
25
+
26
+ def respond_to_missing?(sym)
27
+ sym !~ /[^\w]/ && !!class_for_key(sym)
28
+ end
29
+
30
+ def as_json(options = nil)
31
+ map do |klass, records|
32
+ is_relation = klass < Model::Relation
33
+ [
34
+ klass.name.demodulize.to_sym,
35
+ records.map { |record| is_relation ? record.records.map(&:origin_id) : record.origin_id }
36
+ ]
37
+ end.to_h
38
+ end
39
+
40
+ private
41
+
42
+ def class_for_key(key)
43
+ return key if Class === key and key < Model
44
+ class_name = key.to_s.demodulize.camelize.singularize.to_sym
45
+ if Models.const_defined? class_name
46
+ klass = Models.const_get(class_name)
47
+ klass < Model and klass
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -4,10 +4,30 @@ module Netfira::WebConnect
4
4
  @event_delegates ||= []
5
5
  end
6
6
 
7
- def self.dispatch_event(event, *args)
8
- target = :"on_#{event}"
9
- event_delegates.map do |delegate|
10
- delegate.__send__(target, *args) if delegate.respond_to? target
7
+ def self.dispatch_event(timing, event, *args)
8
+
9
+ # Allow multiple timings to be dispatched simultaneously, e.g. [:on, :after]
10
+ return timing.each{ |t| dispatch_event t, event, *args } if timing.respond_to? :each
11
+
12
+ # The method to invoke, e.g. :on_update_product
13
+ target = :"#{timing}_#{event}"
14
+
15
+ # Delegates that respond to this method
16
+ delegates = event_delegates.select { |d| d.respond_to? target }
17
+
18
+ # 'Around' events get special treatment
19
+ if timing == :around
20
+ chain_runner = -> do
21
+ delegate = delegates.shift
22
+ if delegate
23
+ delegate.__send__ target, *args, &chain_runner
24
+ else
25
+ yield
26
+ end
27
+ end
28
+ chain_runner.call
29
+ else
30
+ delegates.map { |d| d.__send__ target, *args }
11
31
  end
12
32
  end
13
33
 
@@ -25,6 +25,10 @@ module Netfira::WebConnect
25
25
  end
26
26
  end
27
27
 
28
+ def dispatch_event(*args, &block)
29
+ Netfira::WebConnect.dispatch_event *args, &block
30
+ end
31
+
28
32
  end
29
33
  end
30
34
 
@@ -94,6 +94,12 @@ module Netfira::WebConnect
94
94
  instance_variable_set :@readonly, false
95
95
  end
96
96
 
97
+ def as_readwrite
98
+ instance_variable_set :@readonly, false
99
+ yield
100
+ readonly!
101
+ end
102
+
97
103
  def reload
98
104
  clear_translations if has_languages?
99
105
  super
@@ -5,7 +5,7 @@ module Netfira::WebConnect
5
5
 
6
6
  included do
7
7
  around_save :dispatch_create_or_update
8
- before_destroy :dispatch_destroy
8
+ around_destroy :dispatch_destroy
9
9
  end
10
10
 
11
11
  private
@@ -16,20 +16,37 @@ module Netfira::WebConnect
16
16
  value = Checksum.new(value) if value and (key == 'checksum' or key == 'digest')
17
17
  [key, value]
18
18
  end.to_h
19
- previous.merge! previous_translations if previous && has_languages?
20
- yield
19
+ event_name = previous ? 'update' : 'create'
20
+ event_args = [event_name, self]
21
+ named_event_args = ["#{event_name}_#{self.class.single_name}", self]
22
+ if previous
23
+ previous.merge! previous_translations if has_languages?
24
+ event_args << previous
25
+ named_event_args << previous
26
+ end
21
27
  as_readonly do
22
- if previous
23
- Netfira::WebConnect.dispatch_event "update_#{self.class.single_name}", self, previous
24
- else
25
- Netfira::WebConnect.dispatch_event "create_#{self.class.single_name}", self
28
+ dispatch_event :before, *named_event_args
29
+ dispatch_event :before, *event_args
30
+ dispatch_event :around, *named_event_args do
31
+ dispatch_event(:around, *event_args) { as_readwrite { yield } }
26
32
  end
33
+ dispatch_event [:on, :after], *named_event_args
34
+ dispatch_event [:on, :after], *event_args
27
35
  end
28
36
  end
29
37
 
30
38
  def dispatch_destroy
31
- as_readonly { Netfira::WebConnect.dispatch_event "delete_#{self.class.single_name}", self }
32
- true # Returned so we don't cancel the before_destroy callback chain
39
+ event_args = ['delete', self]
40
+ named_event_args = ["delete_#{self.class.single_name}", self]
41
+ as_readonly do
42
+ dispatch_event [:before, :on], *named_event_args
43
+ dispatch_event [:before, :on], *event_args
44
+ dispatch_event :around, *named_event_args do
45
+ dispatch_event(:around, *event_args) { as_readwrite { yield } }
46
+ end
47
+ dispatch_event :after, *named_event_args
48
+ dispatch_event :after, *event_args
49
+ end
33
50
  end
34
51
 
35
52
  end
@@ -10,7 +10,7 @@ module Netfira::WebConnect
10
10
  wrong_shop: 'Tried to add a record from shop %s to shop %s'
11
11
  }
12
12
  prepare_relation(record, error_messages) do |relation_class, attrs|
13
- relation_class.find_or_create_by attrs
13
+ relation_class.with_deleted.find_or_create_by(attrs).tap { |x| x.restore! if x.destroyed? }
14
14
  end
15
15
  end
16
16
 
@@ -22,7 +22,7 @@ module Netfira::WebConnect
22
22
  wrong_shop: 'Tried to remove a record of shop %s from shop %s'
23
23
  }
24
24
  prepare_relation(record, error_messages) do |relation_class, attrs|
25
- relation_class.where(attrs).destroy_all
25
+ relation_class.with_deleted.find_by(attrs).tap { |x| x.destroy! if x }
26
26
  end
27
27
  end
28
28
 
@@ -12,7 +12,11 @@ module Netfira::WebConnect
12
12
  klass = Class.new(self)
13
13
  Models.const_set "#{name_a}To#{name_b}", klass
14
14
  klass.related_classes = [name_a, name_b].map{ |n| Models.const_get n.camelize.singularize }
15
- klass.acts_as_paranoid if Netfira::WebConnect.paranoia?
15
+ if Netfira::WebConnect.paranoia?
16
+ klass.acts_as_paranoid
17
+ else
18
+ def klass.with_deleted; self end
19
+ end
16
20
  end
17
21
 
18
22
  def related_classes=(classes)
@@ -4,26 +4,36 @@ module Netfira::WebConnect
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- after_save :dispatch_create
8
- after_destroy :dispatch_destroy
7
+ around_save :dispatch_create
8
+ around_destroy :dispatch_destroy
9
9
  end
10
10
 
11
11
  private
12
12
 
13
13
  def dispatch_create
14
- dispatch_relation_event 'add_%s_to_%s'
14
+ dispatch_relation_event(:add, :to) { yield }
15
15
  end
16
16
 
17
17
  def dispatch_destroy
18
- dispatch_relation_event 'remove_%s_from_%s'
18
+ dispatch_relation_event(:remove, :from) { yield }
19
19
  end
20
20
 
21
- def dispatch_relation_event(event_name_template)
21
+ def dispatch_relation_event(action, preposition)
22
22
  [records, records.reverse].each do |records|
23
- event_name = (event_name_template % records.map{ |record| record.class.single_name }).to_sym
23
+ event_name = ("#{action}_%s_#{preposition}_%s" % records.map{ |record| record.class.single_name }).to_sym
24
+ named_event_args = [event_name].concat(records)
25
+ event_args = [action].concat(records)
24
26
  records[0].as_readonly do
25
27
  records[1].as_readonly do
26
- Netfira::WebConnect.dispatch_event event_name, *records
28
+ dispatch_event :before, *named_event_args
29
+ dispatch_event :before, *event_args
30
+ dispatch_event :around, *named_event_args do
31
+ dispatch_event :around, *event_args do
32
+ records[0].as_readwrite { records[1].as_readwrite { yield } }
33
+ end
34
+ end
35
+ dispatch_event [:on, :after], *named_event_args
36
+ dispatch_event [:on, :after], *event_args
27
37
  end
28
38
  end
29
39
  end
@@ -42,14 +42,15 @@ module Netfira::WebConnect
42
42
  old = persisted? ? cast_by_content_type(changed_attributes['value'], changed_attributes['content_type']) : nil
43
43
  yield
44
44
  new = OpenStruct.new(shop: shop, key: key, value: typed_value)
45
- Netfira::WebConnect.dispatch_event 'change_setting', new, old unless old == new.value
45
+ dispatch_event [:on, :after], 'change_setting', new, old unless old == new.value
46
46
  end
47
47
 
48
48
  def dispatch_destroy_event
49
49
  return unless persisted?
50
50
  new = OpenStruct.new(shop: shop, key: key, value: nil)
51
51
  old = typed_value
52
- Netfira::WebConnect.dispatch_event 'change_setting', new, old unless old.nil?
52
+ dispatch_event [:before, :on], 'change_setting', new, old unless old.nil?
53
+ true
53
54
  end
54
55
 
55
56
  end
@@ -28,6 +28,10 @@ module Netfira::WebConnect
28
28
  @headers = ActiveSupport::HashWithIndifferentAccess.new
29
29
  end
30
30
 
31
+ def dispatch_event(*args, &block)
32
+ Netfira::WebConnect.dispatch_event *args, &block
33
+ end
34
+
31
35
  private
32
36
 
33
37
  def self.find_action_classes
@@ -4,8 +4,13 @@ class Netfira::WebConnect::RackApp
4
4
 
5
5
  def call
6
6
  raise MethodNotAllowed unless verb == :put
7
- commit_records input['records'] if input['records']
8
- commit_relations input['relations'] if input['relations']
7
+ dispatch_event :before, :commit, shop
8
+ dispatch_event :around, :commit, shop do
9
+ commit_records input['records'] if input['records']
10
+ commit_relations input['relations'] if input['relations']
11
+ [completed(:records), completed(:relations)]
12
+ end
13
+ dispatch_event [:on, :after], :commit, shop, completed(:records), completed(:relations)
9
14
  {
10
15
  complete: complete,
11
16
  filesToSend: files_to_send
@@ -25,6 +30,10 @@ class Netfira::WebConnect::RackApp
25
30
  }
26
31
  end
27
32
 
33
+ def completed(type)
34
+ (@completed ||= {})[type] ||= Netfira::WebConnect::HashOfModels.new
35
+ end
36
+
28
37
  end
29
38
  end
30
39
  end
@@ -43,6 +43,7 @@ module Netfira::WebConnect
43
43
  end
44
44
 
45
45
  def complete_record(record)
46
+ completed(:records) << record
46
47
  list = complete[:records][record.class.name.demodulize] ||= {}
47
48
  list[record.origin_id.to_s] = record.digest
48
49
  end
@@ -8,8 +8,8 @@ class Netfira::WebConnect::RackApp
8
8
  relations.each do |class_name, relation_sets|
9
9
  klass = class_for_relation_type class_name.sub('&', 'To')
10
10
  relation_sets.each do |relation|
11
- update_relation klass, relation
12
- complete_relation class_name, relation
11
+ relation_model = update_relation(klass, relation)
12
+ complete_relation class_name, relation, relation_model
13
13
  end
14
14
  end
15
15
  end
@@ -38,7 +38,8 @@ class Netfira::WebConnect::RackApp
38
38
  records[0].unrelate records[1] if records.size == 2
39
39
  end
40
40
 
41
- def complete_relation(class_name, relation)
41
+ def complete_relation(class_name, relation, relation_model)
42
+ completed(:relations) << relation_model if relation_model
42
43
  list = complete[:relations][class_name] ||= []
43
44
  list << relation
44
45
  end
@@ -1,6 +1,6 @@
1
1
  module Netfira
2
2
  module WebConnect
3
- VERSION = '0.3.3'
3
+ VERSION = '0.4.0'
4
4
  PLATFORM_AND_VERSION = 'Rack/' << VERSION
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web-connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil E. Pearson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-02 00:00:00.000000000 Z
12
+ date: 2014-08-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -124,6 +124,7 @@ files:
124
124
  - lib/netfira/web_connect/components.rb
125
125
  - lib/netfira/web_connect/components/checksum.rb
126
126
  - lib/netfira/web_connect/components/guid.rb
127
+ - lib/netfira/web_connect/components/hash_of_models.rb
127
128
  - lib/netfira/web_connect/components/octa_word.rb
128
129
  - lib/netfira/web_connect/configuration.rb
129
130
  - lib/netfira/web_connect/db_schema/20140514_support.rb