smooth_operator 1.8.8 → 1.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 +8 -8
- data/console.rb +1 -1
- data/lib/smooth_operator.rb +1 -1
- data/lib/smooth_operator/array_with_meta_data.rb +1 -1
- data/lib/smooth_operator/attribute_assignment.rb +49 -5
- data/lib/smooth_operator/attributes/base.rb +17 -0
- data/lib/smooth_operator/attributes/dirty.rb +31 -0
- data/lib/smooth_operator/helpers.rb +5 -1
- data/lib/smooth_operator/open_struct.rb +15 -7
- data/lib/smooth_operator/type_converter.rb +35 -0
- data/lib/smooth_operator/version.rb +1 -1
- data/spec/factories/user_factory.rb +3 -3
- data/spec/smooth_operator/attribute_assignment_spec.rb +24 -10
- data/spec/smooth_operator/attributes_dirty_spec.rb +53 -0
- data/spec/smooth_operator/delegation_spec.rb +1 -47
- data/spec/smooth_operator/model_schema_spec.rb +1 -1
- data/spec/smooth_operator/operator_spec.rb +1 -1
- data/spec/smooth_operator/validations_spec.rb +1 -1
- data/spec/support/models/address.rb +4 -0
- data/spec/support/models/post.rb +0 -2
- data/spec/support/models/user.rb +25 -7
- data/spec/support/models/user_with_address_and_posts.rb +9 -1
- metadata +5 -2
- data/lib/smooth_operator/internal_attribute.rb +0 -49
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
M2UzYWIwNGJhMGE3YTA4YTUyNjA5MzM2NzdkMTM1MzdjZWFmZjVlYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YTVjOTE5MWM3NmNkNjA3MWUyNmU5M2Y5YThjMDM1NzYwOTQyZjdkMw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
N2YwN2Y3ODg3YzFhZDQxNjA1OWM4YTk3M2ExYTZkZWYxYjhkN2Y4N2M1ZTQw
|
10
|
+
NTllZTBhMGYxOGM3OTU4OTA4ZWUyMGIwNmY2YzM2NTZjNmQ2YmJiMzMwYjE1
|
11
|
+
MmQwYjgwOWI4ZjI5MjU1NTljNTg5MzY0ZWZjM2FiYzk5MDc3YWU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
M2I2NWVhZjExZGYzN2NkYTIwNjM5YWRjNGZlZDQ4Njk5MjNlZGI1YjQzM2U3
|
14
|
+
MmVlNWZkMWUyMDI1Y2ZhMGZmZWUwY2VjYjA2MzYyNWI0YjRmNDlkM2I1MWY4
|
15
|
+
YTVjZTRmZGM4NGY0YzdlNjBmMDAwOTg4YmNiMjFkMWFiYmYxMjA=
|
data/console.rb
CHANGED
data/lib/smooth_operator.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require 'smooth_operator/
|
1
|
+
require 'smooth_operator/attributes/base'
|
2
|
+
require 'smooth_operator/attributes/dirty'
|
2
3
|
|
3
4
|
module SmoothOperator
|
4
5
|
|
@@ -10,7 +11,11 @@ module SmoothOperator
|
|
10
11
|
|
11
12
|
module ClassMethods
|
12
13
|
|
13
|
-
|
14
|
+
attr_writer :unknown_hash_class
|
15
|
+
|
16
|
+
def unknown_hash_class
|
17
|
+
Helpers.get_instance_variable(self, :unknown_hash_class, ::OpenStruct)
|
18
|
+
end
|
14
19
|
|
15
20
|
def attributes_white_list
|
16
21
|
Helpers.get_instance_variable(self, :attributes_white_list, Set.new)
|
@@ -28,6 +33,14 @@ module SmoothOperator
|
|
28
33
|
attributes_black_list.merge getters.map(&:to_s)
|
29
34
|
end
|
30
35
|
|
36
|
+
def dirty_attributes
|
37
|
+
@dirty_attributes = true
|
38
|
+
end
|
39
|
+
|
40
|
+
def dirty_attributes?
|
41
|
+
@dirty_attributes
|
42
|
+
end
|
43
|
+
|
31
44
|
end
|
32
45
|
|
33
46
|
|
@@ -50,7 +63,15 @@ module SmoothOperator
|
|
50
63
|
end
|
51
64
|
|
52
65
|
def get_internal_data(field, method = :value)
|
53
|
-
|
66
|
+
result = internal_data[field]
|
67
|
+
|
68
|
+
if result.nil?
|
69
|
+
nil
|
70
|
+
elsif method == :value
|
71
|
+
result.is_a?(Attributes::Dirty) ? internal_data[field].send(method) : internal_data[field]
|
72
|
+
else
|
73
|
+
internal_data[field].send(method)
|
74
|
+
end
|
54
75
|
end
|
55
76
|
|
56
77
|
def push_to_internal_data(attribute_name, attribute_value)
|
@@ -61,9 +82,9 @@ module SmoothOperator
|
|
61
82
|
known_attributes.add attribute_name
|
62
83
|
|
63
84
|
if internal_data[attribute_name].nil?
|
64
|
-
|
85
|
+
initiate_internal_data(attribute_name, attribute_value)
|
65
86
|
else
|
66
|
-
|
87
|
+
update_internal_data(attribute_name, attribute_value)
|
67
88
|
end
|
68
89
|
end
|
69
90
|
|
@@ -84,6 +105,29 @@ module SmoothOperator
|
|
84
105
|
end
|
85
106
|
end
|
86
107
|
|
108
|
+
|
109
|
+
private ######################## PRIVATE #############################
|
110
|
+
|
111
|
+
def initiate_internal_data(attribute_name, attribute_value)
|
112
|
+
internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value)
|
113
|
+
|
114
|
+
internal_data[attribute_name] = internal_data[attribute_name].value unless self.class.dirty_attributes?
|
115
|
+
end
|
116
|
+
|
117
|
+
def update_internal_data(attribute_name, attribute_value)
|
118
|
+
if self.class.dirty_attributes?
|
119
|
+
internal_data[attribute_name].set_value(attribute_value)
|
120
|
+
else
|
121
|
+
internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def new_attribute_object(attribute_name, attribute_value)
|
126
|
+
attribute_class = self.class.dirty_attributes? ? Attributes::Dirty : Attributes::Base
|
127
|
+
|
128
|
+
attribute_class.new(attribute_name, attribute_value, internal_structure[attribute_name], self.class.unknown_hash_class)
|
129
|
+
end
|
130
|
+
|
87
131
|
end
|
88
132
|
|
89
133
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'smooth_operator/type_converter'
|
2
|
+
|
3
|
+
module SmoothOperator
|
4
|
+
module Attributes
|
5
|
+
|
6
|
+
class Base
|
7
|
+
|
8
|
+
attr_reader :value
|
9
|
+
|
10
|
+
def initialize(name, value, type, unknown_hash_class)
|
11
|
+
@value = TypeConverter.cast_to_type(name, value, type, self.class, unknown_hash_class)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'smooth_operator/type_converter'
|
2
|
+
|
3
|
+
module SmoothOperator
|
4
|
+
module Attributes
|
5
|
+
|
6
|
+
class Dirty
|
7
|
+
|
8
|
+
attr_reader :original_name, :original_value, :first_value, :value, :type, :unknown_hash_class
|
9
|
+
|
10
|
+
def initialize(name, value, type, unknown_hash_class)
|
11
|
+
@original_name, @original_value, @type, @unknown_hash_class = name, value, type, unknown_hash_class
|
12
|
+
|
13
|
+
@first_value = set_value(value)
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_value(new_value)
|
17
|
+
@value = TypeConverter.cast_to_type(original_name, new_value, type, self.class, unknown_hash_class)
|
18
|
+
end
|
19
|
+
|
20
|
+
def changed?
|
21
|
+
@first_value != @value
|
22
|
+
end
|
23
|
+
|
24
|
+
def was
|
25
|
+
@first_value
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -13,8 +13,12 @@ module SmoothOperator
|
|
13
13
|
|
14
14
|
return instance_var unless instance_var.nil?
|
15
15
|
|
16
|
-
(super_method(object, variable) || default_value)
|
16
|
+
instance_var = (super_method(object, variable) || default_value)
|
17
|
+
|
18
|
+
if instance_var.class == Class
|
17
19
|
object.instance_variable_set("@#{variable}", instance_var)
|
20
|
+
else
|
21
|
+
object.instance_variable_set("@#{variable}", duplicate(instance_var))
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
@@ -5,15 +5,23 @@ require "smooth_operator/serialization"
|
|
5
5
|
require "smooth_operator/attribute_assignment"
|
6
6
|
|
7
7
|
module SmoothOperator
|
8
|
+
module OpenStruct
|
8
9
|
|
9
|
-
|
10
|
+
class Base
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
include Delegation
|
13
|
+
include Validations
|
14
|
+
include ModelSchema
|
15
|
+
include Serialization
|
16
|
+
include AttributeAssignment
|
16
17
|
|
17
|
-
|
18
|
+
end
|
19
|
+
|
20
|
+
class Dirty < Base
|
18
21
|
|
22
|
+
dirty_attributes
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
19
27
|
end
|
@@ -4,6 +4,17 @@ module SmoothOperator
|
|
4
4
|
|
5
5
|
extend self
|
6
6
|
|
7
|
+
def cast_to_type(name, value, type, array_class, unknown_hash_class)
|
8
|
+
case value
|
9
|
+
when Array
|
10
|
+
value.map { |array_entry| array_class.new(name, array_entry, type, unknown_hash_class).value }
|
11
|
+
when Hash
|
12
|
+
type.nil? ? new_unknown_hash(value, array_class, unknown_hash_class) : type.new(value)
|
13
|
+
else
|
14
|
+
TypeConverter.convert(value, type)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
7
18
|
def convert(value, type)
|
8
19
|
case type
|
9
20
|
|
@@ -63,6 +74,30 @@ module SmoothOperator
|
|
63
74
|
|
64
75
|
value.nil? ? 0 : value
|
65
76
|
end
|
77
|
+
|
78
|
+
|
79
|
+
protected ################### PROTECTED #####################
|
80
|
+
|
81
|
+
def new_unknown_hash(hash, array_class, unknown_hash_class)
|
82
|
+
if unknown_hash_class == :none
|
83
|
+
hash
|
84
|
+
else
|
85
|
+
unknown_hash_class.new(cast_params(hash, array_class, unknown_hash_class))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
private ################### PRIVATE #####################
|
91
|
+
|
92
|
+
def cast_params(attributes, array_class, unknown_hash_class)
|
93
|
+
hash = {}
|
94
|
+
|
95
|
+
attributes.each do |key, value|
|
96
|
+
hash[key] = cast_to_type(key, value, nil, array_class, unknown_hash_class)
|
97
|
+
end
|
98
|
+
|
99
|
+
hash
|
100
|
+
end
|
66
101
|
|
67
102
|
end
|
68
103
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
|
3
|
-
factory :user, class: User do
|
3
|
+
factory :user, class: User::Base do
|
4
4
|
|
5
5
|
id 1
|
6
6
|
admin true
|
@@ -20,12 +20,12 @@ FactoryGirl.define do
|
|
20
20
|
|
21
21
|
end
|
22
22
|
|
23
|
-
factory :white_list, class: User do
|
23
|
+
factory :white_list, class: User::Base do
|
24
24
|
id 1
|
25
25
|
first_name 'John'
|
26
26
|
end
|
27
27
|
|
28
|
-
factory :black_list, class: User do
|
28
|
+
factory :black_list, class: User::Base do
|
29
29
|
admin true
|
30
30
|
last_name 'Doe'
|
31
31
|
end
|
@@ -34,28 +34,42 @@ describe SmoothOperator::AttributeAssignment do
|
|
34
34
|
context "when something other than a hash is introduced" do
|
35
35
|
it "should do nothing" do
|
36
36
|
[nil, '', [1, 2], 'test', 1, 2].each do |something_other_than_a_hash|
|
37
|
-
expect(User.new(something_other_than_a_hash).internal_data).to eq({})
|
37
|
+
expect(User::Base.new(something_other_than_a_hash).internal_data).to eq({})
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
context "when one of the attribute's value, is an hash and is unknown to the schema" do
|
43
|
-
context "when the .
|
44
|
-
subject { User.new(address: { street: 'something', postal_code: { code: '123' } }) }
|
43
|
+
context "when the .unknown_hash_class is unused" do
|
44
|
+
subject { User::Base.new(address: { street: 'something', postal_code: { code: '123' } }) }
|
45
45
|
|
46
|
-
it "a new instance of
|
46
|
+
it "a new instance of OpenStruct will be initialized with that hash" do
|
47
47
|
address = subject.address
|
48
48
|
|
49
|
-
expect(address).to be_instance_of(
|
49
|
+
expect(address).to be_instance_of(OpenStruct)
|
50
50
|
expect(address.street).to eq('something')
|
51
51
|
|
52
|
-
expect(address.postal_code).to be_instance_of(
|
52
|
+
expect(address.postal_code).to be_instance_of(OpenStruct)
|
53
53
|
expect(address.postal_code.code).to eq('123')
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
57
|
-
context "when the .
|
58
|
-
subject {
|
56
|
+
|
57
|
+
context "when the .unknown_hash_class is set to SmoothOperator::OpenStruct::Base" do
|
58
|
+
subject { User::UnknownHashClass::OpenStructBase.new(address: { street: 'something', postal_code: { code: '123' } }) }
|
59
|
+
|
60
|
+
it "a new instance of SmoothOperator::OpenStruct::Base will be initialized with that hash" do
|
61
|
+
address = subject.address
|
62
|
+
|
63
|
+
expect(address).to be_instance_of(SmoothOperator::OpenStruct::Base)
|
64
|
+
expect(address.street).to eq('something')
|
65
|
+
|
66
|
+
expect(address.postal_code).to be_instance_of(SmoothOperator::OpenStruct::Base)
|
67
|
+
expect(address.postal_code.code).to eq('123')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when the .unknown_hash_class is set to :none" do
|
72
|
+
subject { User::UnknownHashClass::None.new(creator: { first_name: 'admin', address: { street: 'something' } }) }
|
59
73
|
|
60
74
|
it "the hash will be copied as it is" do
|
61
75
|
creator = subject.creator
|
@@ -70,7 +84,7 @@ describe SmoothOperator::AttributeAssignment do
|
|
70
84
|
end
|
71
85
|
|
72
86
|
context "when there is no declared schema" do
|
73
|
-
subject { User.new(attributes_for(:user)) }
|
87
|
+
subject { User::Base.new(attributes_for(:user)) }
|
74
88
|
let(:expected_internal_data) { SmoothOperator::Helpers.stringify_keys(attributes_for(:user)) }
|
75
89
|
|
76
90
|
it "it should populate 'internal_data' with unaltered duplicate data from the received hash" do
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe SmoothOperator::Attributes::Dirty do
|
4
|
+
|
5
|
+
subject { UserWithAddressAndPosts::DirtyAttributes.new(attributes_for(:user_with_address_and_posts)) }
|
6
|
+
|
7
|
+
context "when no changes are made to an attribute" do
|
8
|
+
it "checking if that attribute is changed, should return false" do
|
9
|
+
expect(subject.first_name_changed?).to be false
|
10
|
+
end
|
11
|
+
|
12
|
+
it "checking that attribute past value, should its original value" do
|
13
|
+
expect(subject.first_name_was).to eq('John')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when there are changes made to an attribute" do
|
18
|
+
before { subject.first_name = 'nhoJ' }
|
19
|
+
|
20
|
+
it "checking if that attribute is changed, should return true" do
|
21
|
+
expect(subject.first_name_changed?).to be true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "checking that attribute past value, should its original value" do
|
25
|
+
expect(subject.first_name_was).to eq('John')
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when there are changes to the changes made to an attribute" do
|
29
|
+
before { subject.first_name = 'no_name' }
|
30
|
+
|
31
|
+
it "checking if that attribute is changed, should return true" do
|
32
|
+
expect(subject.first_name_changed?).to be true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "checking that attribute past value, should its first original value" do
|
36
|
+
expect(subject.first_name_was).to eq('John')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when there are changes made to a nested object" do
|
42
|
+
before { subject.address.street = 'my street' }
|
43
|
+
|
44
|
+
it "checking if the nested object as changed, should return false" do
|
45
|
+
expect(subject.address_changed?).to be false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "checking if the nested object's attribute as changed, should return true" do
|
49
|
+
expect(subject.address.street_changed?).to be true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -45,7 +45,7 @@ describe SmoothOperator::Delegation do
|
|
45
45
|
describe "#method_missing" do
|
46
46
|
|
47
47
|
context "when calling a method that matches the initialized attributes" do
|
48
|
-
subject { User.new(attributes_for(:user)) }
|
48
|
+
subject { User::Base.new(attributes_for(:user)) }
|
49
49
|
|
50
50
|
it 'it should return the value of that same attribute' do
|
51
51
|
attributes_for(:user).each do |key, value|
|
@@ -85,52 +85,6 @@ describe SmoothOperator::Delegation do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
context "when no changes are made to an attribute" do
|
89
|
-
it "checking it that attribute is changed, should return false" do
|
90
|
-
expect(subject.first_name_changed?).to be false
|
91
|
-
end
|
92
|
-
|
93
|
-
it "checking that attribute past value, should its original value" do
|
94
|
-
expect(subject.first_name_was).to eq('John')
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context "when there are changes made to an attribute" do
|
99
|
-
before { subject.first_name = 'nhoJ' }
|
100
|
-
|
101
|
-
it "checking if that attribute is changed, should return true" do
|
102
|
-
expect(subject.first_name_changed?).to be true
|
103
|
-
end
|
104
|
-
|
105
|
-
it "checking that attribute past value, should its original value" do
|
106
|
-
expect(subject.first_name_was).to eq('John')
|
107
|
-
end
|
108
|
-
|
109
|
-
context "when there are changes to the changes made to an attribute" do
|
110
|
-
before { subject.first_name = 'no_name' }
|
111
|
-
|
112
|
-
it "checking it that attribute is changed, should return true" do
|
113
|
-
expect(subject.first_name_changed?).to be true
|
114
|
-
end
|
115
|
-
|
116
|
-
it "checking that attribute past value, should its first original value" do
|
117
|
-
expect(subject.first_name_was).to eq('John')
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
context "when there are changes made to a nested object" do
|
123
|
-
before { subject.address.street = 'my street' }
|
124
|
-
|
125
|
-
it "checking if the nested object as changed, should return false" do
|
126
|
-
expect(subject.address_changed?).to be false
|
127
|
-
end
|
128
|
-
|
129
|
-
it "checking if the nested object's attribute as changed, should return true" do
|
130
|
-
expect(subject.address.street_changed?).to be true
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
88
|
end
|
135
89
|
|
136
90
|
end
|
@@ -6,7 +6,7 @@ describe SmoothOperator::ModelSchema do
|
|
6
6
|
let(:initial_attributes_keys) { attributes_for(:user).keys.map(&:to_s) }
|
7
7
|
|
8
8
|
context "when there is no declared schema" do
|
9
|
-
subject { User.new(attributes_for(:user)) }
|
9
|
+
subject { User::Base.new(attributes_for(:user)) }
|
10
10
|
|
11
11
|
it 'it should reflect the attributes used uppon initialization' do
|
12
12
|
expect(subject.known_attributes.to_a).to match_array(initial_attributes_keys)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe SmoothOperator::Validations do
|
4
|
-
subject { User.new(attributes_for(:user)) }
|
4
|
+
subject { User::Base.new(attributes_for(:user)) }
|
5
5
|
|
6
6
|
describe "#valid?" do
|
7
7
|
context "when executing a persistence method, and the server response has a hash with the key 'errors'" do
|
@@ -1,4 +1,7 @@
|
|
1
1
|
class Address < SmoothOperator::Base
|
2
|
+
|
3
|
+
self.dirty_attributes
|
4
|
+
|
2
5
|
self.model_name = :none
|
3
6
|
|
4
7
|
self.endpoint_user = 'admin'
|
@@ -7,4 +10,5 @@ class Address < SmoothOperator::Base
|
|
7
10
|
self.endpoint = 'http://localhost:4567/'
|
8
11
|
|
9
12
|
self.headers = { "X-APPTOKEN" => "joaquim_app_token", "X-LAYERTOKEN" => "joaquim_layer_token" }
|
13
|
+
|
10
14
|
end
|
data/spec/support/models/post.rb
CHANGED
data/spec/support/models/user.rb
CHANGED
@@ -1,15 +1,33 @@
|
|
1
|
-
|
1
|
+
module User
|
2
|
+
|
3
|
+
class Base < SmoothOperator::Base
|
2
4
|
|
3
|
-
|
5
|
+
self.model_name = 'user'
|
4
6
|
|
5
|
-
|
7
|
+
self.endpoint_user = 'admin'
|
6
8
|
|
7
|
-
|
9
|
+
self.endpoint_pass = 'admin'
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
self.endpoint = 'http://localhost:4567/'
|
12
|
+
|
13
|
+
def self.query_string(params)
|
14
|
+
params['query_string_param'] = true
|
15
|
+
|
16
|
+
params
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
module UnknownHashClass
|
22
|
+
|
23
|
+
class OpenStructBase < User::Base
|
24
|
+
self.unknown_hash_class = SmoothOperator::OpenStruct::Base
|
25
|
+
end
|
26
|
+
|
27
|
+
class None < User::Base
|
28
|
+
self.unknown_hash_class = :none
|
29
|
+
end
|
11
30
|
|
12
|
-
params
|
13
31
|
end
|
14
32
|
|
15
33
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module UserWithAddressAndPosts
|
2
2
|
|
3
|
-
class Father < User
|
3
|
+
class Father < User::Base
|
4
4
|
|
5
5
|
schema(
|
6
6
|
posts: Post,
|
@@ -70,4 +70,12 @@ module UserWithAddressAndPosts
|
|
70
70
|
|
71
71
|
end
|
72
72
|
|
73
|
+
class DirtyAttributes < UserWithAddressAndPosts::Son
|
74
|
+
|
75
|
+
self.dirty_attributes
|
76
|
+
|
77
|
+
self.unknown_hash_class = SmoothOperator::OpenStruct::Dirty
|
78
|
+
|
79
|
+
end
|
80
|
+
|
73
81
|
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.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- João Gonçalves
|
@@ -69,10 +69,11 @@ files:
|
|
69
69
|
- lib/smooth_operator.rb
|
70
70
|
- lib/smooth_operator/array_with_meta_data.rb
|
71
71
|
- lib/smooth_operator/attribute_assignment.rb
|
72
|
+
- lib/smooth_operator/attributes/base.rb
|
73
|
+
- lib/smooth_operator/attributes/dirty.rb
|
72
74
|
- lib/smooth_operator/delegation.rb
|
73
75
|
- lib/smooth_operator/finder_methods.rb
|
74
76
|
- lib/smooth_operator/helpers.rb
|
75
|
-
- lib/smooth_operator/internal_attribute.rb
|
76
77
|
- lib/smooth_operator/model_schema.rb
|
77
78
|
- lib/smooth_operator/open_struct.rb
|
78
79
|
- lib/smooth_operator/operator.rb
|
@@ -86,6 +87,7 @@ files:
|
|
86
87
|
- smooth_operator.gemspec
|
87
88
|
- spec/factories/user_factory.rb
|
88
89
|
- spec/smooth_operator/attribute_assignment_spec.rb
|
90
|
+
- spec/smooth_operator/attributes_dirty_spec.rb
|
89
91
|
- spec/smooth_operator/delegation_spec.rb
|
90
92
|
- spec/smooth_operator/finder_methods_spec.rb
|
91
93
|
- spec/smooth_operator/model_schema_spec.rb
|
@@ -130,6 +132,7 @@ summary: Simple and fully customizable alternative to ActiveResource, using fara
|
|
130
132
|
test_files:
|
131
133
|
- spec/factories/user_factory.rb
|
132
134
|
- spec/smooth_operator/attribute_assignment_spec.rb
|
135
|
+
- spec/smooth_operator/attributes_dirty_spec.rb
|
133
136
|
- spec/smooth_operator/delegation_spec.rb
|
134
137
|
- spec/smooth_operator/finder_methods_spec.rb
|
135
138
|
- spec/smooth_operator/model_schema_spec.rb
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'smooth_operator/type_converter'
|
2
|
-
|
3
|
-
module SmoothOperator
|
4
|
-
|
5
|
-
class InternalAttribute
|
6
|
-
|
7
|
-
attr_reader :original_name, :original_value, :first_value, :value, :type, :turn_unknown_hash_to_open_struct
|
8
|
-
|
9
|
-
def initialize(name, value, type, turn_to_open_struct = nil)
|
10
|
-
@original_name, @original_value, @type = name, value, type
|
11
|
-
|
12
|
-
@turn_unknown_hash_to_open_struct = turn_to_open_struct.nil? ? true : turn_to_open_struct
|
13
|
-
|
14
|
-
@first_value = set_value(value)
|
15
|
-
end
|
16
|
-
|
17
|
-
def set_value(new_value)
|
18
|
-
@value = cast_to_type(new_value)
|
19
|
-
end
|
20
|
-
|
21
|
-
def changed?
|
22
|
-
@first_value != @value
|
23
|
-
end
|
24
|
-
|
25
|
-
def was
|
26
|
-
@first_value
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
protected ######################## PROTECTED #####################
|
31
|
-
|
32
|
-
def cast_to_type(_value)
|
33
|
-
case _value
|
34
|
-
when Array
|
35
|
-
_value.map { |array_entry| InternalAttribute.new(original_name, array_entry, type, turn_unknown_hash_to_open_struct).value }
|
36
|
-
when Hash
|
37
|
-
if turn_unknown_hash_to_open_struct
|
38
|
-
(type || OpenStruct).new(_value)
|
39
|
-
else
|
40
|
-
type.nil? ? _value : type.new(_value)
|
41
|
-
end
|
42
|
-
else
|
43
|
-
TypeConverter.convert(_value, type)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|