smooth_operator 1.2.1 → 1.2.5

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTBiYTliODQ1NDM1MGU5NjlkMTVhNGJiMTExNjY3YjU4YjgzODQ2OA==
4
+ Yzk0YmZmM2Q1NDE4YWY5YWYxOTYyZjZkYTk2NjBjNjQ4MjMxNDU4ZQ==
5
5
  data.tar.gz: !binary |-
6
- MDZkYjJmYTdlM2M3NmZmZmFlODVhMWZkNTBlNWQ1ZjNmZDg2YmY4YQ==
6
+ OTllZjJjMDgyOGYxY2VkZmM4NWUzN2Y3Y2E5NTgxZjdlMDU5NjE1Ng==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YmRkOTExMDUzY2QwNDQ0ZTYwNDk2Y2FhYTE0YzA0YzkyYzg1ZDYwNjhjMTBm
10
- YzBiNzg5NDNlY2YxZTZjZThjNTljYmEwNTQwMjAwNGY5ZGI0YjE2MWFjNmVl
11
- ODNiYWNhNDVjMzIyZjIzMTkxNGE1MDYyYmQ0YWEwNWZjNDA3YjE=
9
+ YTgzYjIwYWEyMjE2YmJmZjk2YzllOWQyNWUwOWJjZTBlYjdjZDMxOTIwOWRh
10
+ NmQ0MTc5NWQ4NDY1ZjMzMWM4MzljODk4OTEwOWM0MjQyN2JjODA2NjYwMGEz
11
+ OTMzYjZlOTc2ZWY4YzU2ODNjOWE2MWYxMmIyYzJhNjE1ZTU3YTM=
12
12
  data.tar.gz: !binary |-
13
- MTFmMmNjOGYwZTNjN2ZhNzczMWE3OGRhMTYyYjFkOTVjM2ZlNTRlYTgyNDE4
14
- NzJkYjZjMGI5MzU1NTliOWJlMGQ0M2QzYzg4MDI5NjhjMDIwNDVlNmZlOTBl
15
- OWVkZjM2MzM1ODc4OTg1MmE3NWIzMmE1N2NhMTIxMTU5NmI5N2E=
13
+ YmU2NDdkOTY3ZjEwOGFkMzNiMDJiNzAzM2NlYjM4MDc1NTc4MDI0N2JjMDEx
14
+ YzNkYTRlNWU2MDU4NzJmMjU2N2Q3NDExODkyNTU2YjJkZWFlNmFjOGM0N2Vl
15
+ ZmUxMTU4YTI2YzFiYTU1YTNlNTNkYjNlYTg0N2U5NThmZDQzZTg=
data/console.rb CHANGED
@@ -29,16 +29,6 @@ LocalhostServer.new(TestServer.new, 4567)
29
29
 
30
30
  post = Post.new(comments: [{ id: 1, name: '1' }, { id: 2, name: '2' }], address: { id: 1, name: 'address' })
31
31
 
32
- class Test < SimpleDelegator
33
- def reload
34
- "TODO"
35
- end
36
- end
37
-
38
- class Test2 < Test
39
- def reload2
40
- "TODO2"
41
- end
42
- end
32
+ comments_attributes = { "0" => { id: 1, name: '3' }, "1" => { name: '4' } }
43
33
 
44
34
  binding.pry
@@ -1,14 +1,8 @@
1
1
  module SmoothOperator
2
- class ArrayWithMetaData < OpenStruct::Base
3
-
4
- extend Forwardable
5
-
6
- include Enumerable
2
+ class ArrayWithMetaData < ::SimpleDelegator
7
3
 
8
4
  attr_reader :meta_data, :internal_array
9
5
 
10
- def_delegators :internal_array, :length, :<<, :[]
11
-
12
6
  def initialize(attributes, object_class)
13
7
  _attributes, _resources_name = attributes.dup, object_class.resources_name
14
8
 
@@ -16,10 +10,8 @@ module SmoothOperator
16
10
  _attributes.delete(_resources_name)
17
11
 
18
12
  @meta_data = _attributes
19
- end
20
13
 
21
- def each
22
- internal_array.each { |array_entry| yield array_entry }
14
+ super(@internal_array)
23
15
  end
24
16
 
25
17
  def method_missing(method, *args, &block)
@@ -3,7 +3,6 @@ require 'smooth_operator/attributes/dirty'
3
3
  require 'smooth_operator/attributes/normal'
4
4
 
5
5
  module SmoothOperator
6
-
7
6
  module AttributeAssignment
8
7
 
9
8
  def self.included(base)
@@ -69,7 +68,7 @@ module SmoothOperator
69
68
 
70
69
  options.each { |key, value| @_options[key] = value } if options.is_a?(Hash)
71
70
 
72
- attributes.each { |name, value| push_to_internal_data(name, value, true) }
71
+ attributes.each { |name, value| push_to_internal_data(name, value) }
73
72
  end
74
73
 
75
74
  def parent_object
@@ -21,36 +21,45 @@ module SmoothOperator
21
21
  self.class.internal_structure[attribute.to_s]
22
22
  end
23
23
 
24
- def push_to_internal_data(attribute_name, attribute_value, cast = false)
24
+ def push_to_internal_data(attribute_name, attribute_value)
25
25
  attribute_name = attribute_name.to_s
26
26
 
27
27
  return nil unless allowed_attribute(attribute_name)
28
28
 
29
29
  known_attributes.add attribute_name
30
30
 
31
- if internal_data[attribute_name].nil?
32
- initiate_internal_data(attribute_name, attribute_value, cast)
33
- else
34
- update_internal_data(attribute_name, attribute_value, cast)
35
- end
31
+ attribute_name, attribute_value = extract_nested_attributes(attribute_name, attribute_value)
32
+
33
+ initiate_or_update_internal_data(attribute_name, attribute_value)
34
+
35
+ new_record_or_mark_for_destruction?(attribute_name, attribute_value)
36
+ end
37
+
38
+ protected #################### PROTECTED METHODS DOWN BELOW ######################
36
39
 
37
- if self.class.respond_to?(:smooth_operator?)
38
- trigger_necessary_events(attribute_name, attribute_value)
40
+ def extract_nested_attributes(attribute_name, attribute_value)
41
+ if !!(attribute_name =~ /_attributes$/)
42
+ attribute_name = attribute_name[0..-12]
43
+
44
+ if self.class.reflect_on_association(attribute_name.to_sym).has_many?
45
+ attribute_value = attribute_value.values
46
+ end
39
47
  end
48
+
49
+ [attribute_name, attribute_value]
40
50
  end
41
51
 
42
- def column_for_attribute(attribute_name)
43
- if defined?(ActiveRecord)
44
- type = get_attribute_type(attribute_name)
45
- ActiveRecord::ConnectionAdapters::Column.new(attribute_name.to_sym, type, type)
52
+ def initiate_or_update_internal_data(attribute_name, attribute_value)
53
+ if internal_data[attribute_name].nil?
54
+ initiate_internal_data(attribute_name, attribute_value)
46
55
  else
47
- nil
56
+ update_internal_data(attribute_name, attribute_value)
48
57
  end
49
58
  end
50
59
 
51
- protected #################### PROTECTED METHODS DOWN BELOW ######################
60
+ def new_record_or_mark_for_destruction?(attribute_name, attribute_value)
61
+ return nil unless self.class.respond_to?(:smooth_operator?)
52
62
 
53
- def trigger_necessary_events(attribute_name, attribute_value)
54
63
  mark_for_destruction?(attribute_value) if attribute_name == self.class.destroy_key
55
64
 
56
65
  new_record?(true) if attribute_name == self.class.primary_key
@@ -58,21 +67,17 @@ module SmoothOperator
58
67
 
59
68
  private ######################## PRIVATE #############################
60
69
 
61
- def initiate_internal_data(attribute_name, attribute_value, cast)
62
- if cast
63
- internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value)
70
+ def initiate_internal_data(attribute_name, attribute_value)
71
+ internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value)
64
72
 
65
- internal_data[attribute_name] = internal_data[attribute_name].value unless self.class.dirty_attributes?
66
- else
67
- internal_data[attribute_name] = attribute_value
68
- end
73
+ internal_data[attribute_name] = internal_data[attribute_name].value unless self.class.dirty_attributes?
69
74
  end
70
75
 
71
- def update_internal_data(attribute_name, attribute_value, cast)
76
+ def update_internal_data(attribute_name, attribute_value)
72
77
  if self.class.dirty_attributes?
73
78
  internal_data[attribute_name].set_value(attribute_value, self)
74
79
  else
75
- internal_data[attribute_name] = cast ? new_attribute_object(attribute_name, attribute_value).value : attribute_value
80
+ internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value).value
76
81
  end
77
82
  end
78
83
 
@@ -2,7 +2,7 @@ module SmoothOperator
2
2
 
3
3
  module Delegation
4
4
 
5
- def respond_to?(method)
5
+ def respond_to?(method, include_private = false)
6
6
  if known_attribute?(method)
7
7
  true
8
8
  else
@@ -5,18 +5,17 @@ require "smooth_operator/remote_call/errors/timeout"
5
5
  require "smooth_operator/remote_call/errors/connection_failed"
6
6
 
7
7
  module SmoothOperator
8
-
9
8
  module Operator
10
9
 
11
10
  def make_the_call(http_verb, relative_path = '', data = {}, options = {})
12
11
  options ||= {}
13
-
12
+
14
13
  relative_path = resource_path(relative_path)
15
-
14
+
16
15
  if !parent_object.nil? && options[:ignore_parent] != true
17
16
  options[:resources_name] ||= "#{parent_object.class.resources_name}/#{parent_object.get_primary_key}/#{self.class.resources_name}"
18
17
  end
19
-
18
+
20
19
  self.class.make_the_call(http_verb, relative_path, data, options) do |remote_call|
21
20
  yield(remote_call)
22
21
  end
@@ -34,13 +33,12 @@ module SmoothOperator
34
33
  end
35
34
  end
36
35
 
37
-
38
36
  ########################### MODULES BELLOW ###############################
39
37
 
40
38
  module HttpMethods
41
39
 
42
40
  HTTP_VERBS = %w[get post put patch delete]
43
-
41
+
44
42
  HTTP_VERBS.each do |method|
45
43
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
46
44
  def #{method}(relative_path = '', params = {}, options = {})
@@ -78,7 +76,7 @@ module SmoothOperator
78
76
  else
79
77
  operator_call = Operators::Faraday
80
78
  end
81
-
79
+
82
80
  operator_call.make_the_call(*operator_args) do |remote_call|
83
81
  block_given? ? yield(remote_call) : remote_call
84
82
  end
@@ -88,7 +86,6 @@ module SmoothOperator
88
86
  params
89
87
  end
90
88
 
91
-
92
89
  protected #################### PROTECTED ##################
93
90
 
94
91
  def operator_method_args(http_verb, relative_path, data, options)
@@ -97,7 +94,6 @@ module SmoothOperator
97
94
  [http_verb, resource_path(relative_path, options), *strip_params(http_verb, data), options]
98
95
  end
99
96
 
100
-
101
97
  private #################### PRIVATE ##################
102
98
 
103
99
  def populate_options(options)
@@ -106,7 +102,7 @@ module SmoothOperator
106
102
  OPTIONS.each { |option| options[option] ||= send(option) }
107
103
 
108
104
  options[:headers] = headers.merge(options[:headers] || {})
109
-
105
+
110
106
  options
111
107
  end
112
108
 
@@ -122,17 +118,15 @@ module SmoothOperator
122
118
 
123
119
  def strip_params(http_verb, data)
124
120
  data ||= {}
125
-
121
+
126
122
  if [:get, :head, :delete].include?(http_verb)
127
123
  [query_string(data), nil]
128
124
  else
129
125
  [query_string({}), data]
130
126
  end
131
127
  end
132
-
133
128
  end
134
129
 
135
-
136
130
  include HttpMethods
137
131
 
138
132
  def self.included(base)
@@ -4,8 +4,12 @@ module SmoothOperator
4
4
  module Relation
5
5
  class ArrayRelation < SingleRelation
6
6
 
7
- def reload2
8
- "TODO2"
7
+ def data
8
+ super || []
9
+ end
10
+
11
+ def reload
12
+ "TODO"
9
13
  end
10
14
 
11
15
  end
@@ -10,13 +10,29 @@ module SmoothOperator
10
10
  end
11
11
 
12
12
  def get_relation(relation_name)
13
- relations[relation_name] ||= self.class.build_relation(relation_name, get_internal_data(relation_name))
13
+ if relations.include?(relation_name)
14
+ relations[relation_name]
15
+ else
16
+ relations[relation_name] = build_relation(relation_name)
17
+ end
14
18
  end
15
19
 
16
20
  def self.included(base)
17
21
  base.extend(ClassMethods)
18
22
  end
19
23
 
24
+ protected ################### PROTECTED ###################
25
+
26
+ def build_relation(relation_name)
27
+ if self.class.reflect_on_association(relation_name.to_sym).has_many?
28
+ ArrayRelation.new(self, relation_name)
29
+ elsif Helpers.present? get_internal_data(relation_name)
30
+ SingleRelation.new(self, relation_name)
31
+ else
32
+ nil
33
+ end
34
+ end
35
+
20
36
  module ClassMethods
21
37
 
22
38
  def has_many(nested_object_name, options = {})
@@ -43,32 +59,26 @@ module SmoothOperator
43
59
  macro ? reflections.values.select { |reflection| reflection.macro == macro } : reflections.values
44
60
  end
45
61
 
46
- def build_relation(relation_name, data)
47
- if reflections[relation_name.to_sym].has_many?
48
- ArrayRelation.new(data || [], relation_name)
49
- else
50
- SingleRelation.new(data, relation_name)
51
- end
52
- end
53
-
54
62
  protected ###################### PROTECTED ###################
55
63
 
56
64
  def accepts_nested_objects(nested_object_name, macro, options = {})
57
- default_options = { macro: macro }
58
- options = options.is_a?(Hash) ? options.merge(default_options) : default_options
59
- options = Helpers.symbolyze_keys(options)
65
+ options = parse_options(options, { macro: macro })
60
66
 
61
67
  reflection = AssociationReflection.new(nested_object_name, Reflection.new(name, {}), options)
62
68
 
63
- self.send(:attr_accessor, "#{nested_object_name}_attributes".to_sym)
64
- self.instance_variable_set("@reflections", reflections.merge(nested_object_name => reflection))
65
-
66
- define_method("existing_#{nested_object_name}") { existing_nested_objects(nested_object_name) }
67
- define_method("build_#{reflection.single_name}") { |attributes = {}, nested_object = nil| build_nested_object(nested_object_name, attributes, nested_object) }
69
+ reflections.merge!(nested_object_name => reflection)
68
70
 
69
71
  schema(nested_object_name => reflection.klass)
70
72
  end
71
73
 
74
+ private ####################### PRIVATE ######################
75
+
76
+ def parse_options(options, default_options)
77
+ options = options.is_a?(Hash) ? options.merge(default_options) : default_options
78
+
79
+ Helpers.symbolyze_keys(options)
80
+ end
81
+
72
82
  end
73
83
  end
74
84
  end
@@ -1,16 +1,19 @@
1
1
  module SmoothOperator
2
2
  module Relation
3
- class SingleRelation < ::SimpleDelegator
3
+ class SingleRelation
4
4
 
5
5
  attr_reader :object, :relation_name
6
6
 
7
7
  def initialize(object, relation_name)
8
8
  @object, @relation_name = object, relation_name
9
- super(object)
10
9
  end
11
10
 
12
- def persisted?
13
- object.nil? ? false : object.persisted?
11
+ def method_missing(method, *args, &block)
12
+ data.respond_to?(method) ? data.send(method, *args) : super
13
+ end
14
+
15
+ def data
16
+ object.get_internal_data(relation_name)
14
17
  end
15
18
 
16
19
  end
@@ -14,7 +14,6 @@ module SmoothOperator
14
14
  @response = response
15
15
  end
16
16
 
17
-
18
17
  def ok?
19
18
  http_status.between?(200, 299) || http_status == 304
20
19
  end
@@ -35,7 +34,6 @@ module SmoothOperator
35
34
  http_status.between?(500, 599) || http_status == 0
36
35
  end
37
36
 
38
-
39
37
  def not_found?
40
38
  http_status == 404
41
39
  end
@@ -48,12 +46,11 @@ module SmoothOperator
48
46
  false
49
47
  end
50
48
 
51
-
52
49
  def parsed_response
53
50
  return nil if body.nil?
54
-
51
+
55
52
  require 'json' unless defined? JSON
56
-
53
+
57
54
  begin
58
55
  JSON.parse(body)
59
56
  rescue JSON::ParserError
@@ -74,7 +71,5 @@ module SmoothOperator
74
71
  end
75
72
 
76
73
  end
77
-
78
74
  end
79
-
80
75
  end
@@ -1,27 +1,24 @@
1
1
  module SmoothOperator
2
-
3
2
  module Translation
4
3
 
5
4
  def human_attribute_name(attribute_key_name, options = {})
6
5
  _translate("attributes.#{model_name.i18n_key}.#{attribute_key_name}", options = {})
7
6
  end
8
7
 
9
-
10
8
  private ###################### PRIVATE #########################
11
9
 
12
10
  def _translate(namespace = '', options = {})
13
11
  no_translation = "-- no translation --"
14
-
12
+
15
13
  defaults = ["smooth_operator.#{namespace}".to_sym]
16
14
  defaults << "activerecord.#{namespace}".to_sym
17
15
  defaults << options[:default] if options[:default]
18
16
  defaults.flatten!
19
17
  defaults << no_translation
20
-
18
+
21
19
  options = { count: 1, default: defaults }.merge!(options.except(:default))
22
20
  I18n.translate(defaults.shift, options)
23
21
  end
24
22
 
25
23
  end
26
-
27
24
  end
@@ -1,3 +1,3 @@
1
1
  module SmoothOperator
2
- VERSION = "1.2.1"
2
+ VERSION = "1.2.5"
3
3
  end
@@ -25,4 +25,20 @@ module SmoothOperator
25
25
  end
26
26
 
27
27
  end
28
+
29
+ if defined?(ActiveModel)
30
+ class Rails < Base
31
+
32
+ include ActiveModel::Validations
33
+ include ActiveModel::Validations::Callbacks
34
+ include ActiveModel::Conversion
35
+
36
+ def column_for_attribute(attribute_name)
37
+ type = get_attribute_type(attribute_name)
38
+
39
+ ActiveRecord::ConnectionAdapters::Column.new(attribute_name.to_sym, type, type)
40
+ end
41
+
42
+ end
43
+ end
28
44
  end
@@ -10,5 +10,5 @@ class Address < SmoothOperator::Base
10
10
  self.endpoint = 'http://localhost:4567/'
11
11
 
12
12
  self.headers = { "X-APPTOKEN" => "joaquim_app_token", "X-LAYERTOKEN" => "joaquim_layer_token" }
13
-
13
+
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smooth_operator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - João Gonçalves