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 +8 -8
- data/console.rb +1 -11
- data/lib/smooth_operator/array_with_meta_data.rb +2 -10
- data/lib/smooth_operator/attribute_assignment.rb +1 -2
- data/lib/smooth_operator/attribute_methods.rb +29 -24
- data/lib/smooth_operator/delegation.rb +1 -1
- data/lib/smooth_operator/operator.rb +7 -13
- data/lib/smooth_operator/relation/array_relation.rb +6 -2
- data/lib/smooth_operator/relation/associations.rb +27 -17
- data/lib/smooth_operator/relation/single_relation.rb +7 -4
- data/lib/smooth_operator/remote_call/base.rb +2 -7
- data/lib/smooth_operator/translation.rb +2 -5
- data/lib/smooth_operator/version.rb +1 -1
- data/lib/smooth_operator.rb +16 -0
- data/spec/support/models/address.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Yzk0YmZmM2Q1NDE4YWY5YWYxOTYyZjZkYTk2NjBjNjQ4MjMxNDU4ZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTllZjJjMDgyOGYxY2VkZmM4NWUzN2Y3Y2E5NTgxZjdlMDU5NjE1Ng==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTgzYjIwYWEyMjE2YmJmZjk2YzllOWQyNWUwOWJjZTBlYjdjZDMxOTIwOWRh
|
10
|
+
NmQ0MTc5NWQ4NDY1ZjMzMWM4MzljODk4OTEwOWM0MjQyN2JjODA2NjYwMGEz
|
11
|
+
OTMzYjZlOTc2ZWY4YzU2ODNjOWE2MWYxMmIyYzJhNjE1ZTU3YTM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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 <
|
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
|
-
|
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
|
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
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
38
|
-
|
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
|
43
|
-
if
|
44
|
-
|
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
|
-
|
56
|
+
update_internal_data(attribute_name, attribute_value)
|
48
57
|
end
|
49
58
|
end
|
50
59
|
|
51
|
-
|
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
|
62
|
-
|
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
|
-
|
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
|
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] =
|
80
|
+
internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value).value
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
@@ -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)
|
@@ -10,13 +10,29 @@ module SmoothOperator
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def get_relation(relation_name)
|
13
|
-
relations
|
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
|
-
|
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
|
-
|
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
|
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
|
13
|
-
|
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
|
data/lib/smooth_operator.rb
CHANGED
@@ -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
|