smooth_operator 1.2.1 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
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