rest-in-peace 2.0.4 → 3.0.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.
- data/.travis.yml +6 -0
- data/README.md +5 -3
- data/VERSION +1 -1
- data/gemfiles/Gemfile.rails-3.2.x +5 -0
- data/gemfiles/Gemfile.rails-4.0.x +5 -0
- data/gemfiles/Gemfile.rails-4.1.x +5 -0
- data/gemfiles/Gemfile.rails-4.2.x +5 -0
- data/lib/rest_in_peace/active_model_api.rb +2 -14
- data/lib/rest_in_peace/definition_proxy/attributes_definitions.rb +18 -1
- data/lib/rest_in_peace.rb +18 -2
- data/spec/rest_in_peace/active_model_api_spec.rb +0 -21
- data/spec/rest_in_peace_spec.rb +49 -8
- metadata +22 -4
- checksums.yaml +0 -15
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -36,11 +36,13 @@ rest_in_peace do
|
|
36
36
|
end
|
37
37
|
```
|
38
38
|
|
39
|
+
**There must be at least an attribute called `id` to allow REST-in-Peace to work properly.**
|
40
|
+
|
39
41
|
#### API Endpoints
|
40
42
|
|
41
|
-
You need to define all the API endpoints you want to consume with `RESTinPeace`. Currently the four HTTP
|
43
|
+
You need to define all the API endpoints you want to consume with `RESTinPeace`. Currently the four HTTP verbs `GET`, `POST`, `PATCH` and `DELETE` are supported.
|
42
44
|
|
43
|
-
There are two sections where you can specify endpoints: `resource` and `collection
|
45
|
+
There are two sections where you can specify endpoints: `resource` and `collection`. `collection` supports the HTTP verb `GET` only.
|
44
46
|
|
45
47
|
```ruby
|
46
48
|
rest_in_peace do
|
@@ -95,7 +97,7 @@ resource.create # calls "POST /rip"
|
|
95
97
|
resource.reload # calls "GET /rip/1"
|
96
98
|
```
|
97
99
|
|
98
|
-
**For any writing action (`:post`, `:put`, `:patch`) RESTinPeace will include the
|
100
|
+
**For any writing action (`:post`, `:put`, `:patch`) RESTinPeace will include the *changed* attributes in the body and `id`.**
|
99
101
|
|
100
102
|
#### Collection
|
101
103
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.0
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_model'
|
2
|
+
require 'active_support/core_ext/object/blank'
|
2
3
|
|
3
4
|
module RESTinPeace
|
4
5
|
module ActiveModelAPI
|
@@ -12,25 +13,12 @@ module RESTinPeace
|
|
12
13
|
def self.included(base)
|
13
14
|
check_for_missing_methods(base)
|
14
15
|
|
15
|
-
base.send(:include, ActiveModel::Dirty)
|
16
16
|
base.send(:include, ActiveModel::Conversion)
|
17
17
|
base.extend ActiveModel::Naming
|
18
18
|
|
19
19
|
base.send(:alias_method, :save_without_dirty_tracking, :save)
|
20
20
|
base.send(:alias_method, :save, :save_with_dirty_tracking)
|
21
21
|
|
22
|
-
base.send :define_attribute_methods, base.rip_attributes[:write]
|
23
|
-
|
24
|
-
base.rip_attributes[:write].each do |attribute|
|
25
|
-
base.send(:define_method, "#{attribute}_with_dirty_tracking=") do |value|
|
26
|
-
attribute_will_change!(attribute) unless send(attribute) == value
|
27
|
-
send("#{attribute}_without_dirty_tracking=", value)
|
28
|
-
end
|
29
|
-
|
30
|
-
base.send(:alias_method, "#{attribute}_without_dirty_tracking=", "#{attribute}=")
|
31
|
-
base.send(:alias_method, "#{attribute}=", "#{attribute}_with_dirty_tracking=")
|
32
|
-
end
|
33
|
-
|
34
22
|
def base.human_attribute_name(attr, options = {})
|
35
23
|
attr.to_s
|
36
24
|
end
|
@@ -47,7 +35,7 @@ module RESTinPeace
|
|
47
35
|
|
48
36
|
def save_with_dirty_tracking
|
49
37
|
save_without_dirty_tracking.tap do
|
50
|
-
|
38
|
+
clear_changes
|
51
39
|
end
|
52
40
|
end
|
53
41
|
|
@@ -12,8 +12,25 @@ module RESTinPeace
|
|
12
12
|
|
13
13
|
def write(*attributes)
|
14
14
|
read(*attributes)
|
15
|
-
@target.send
|
15
|
+
@target.send :attr_writer, *attributes
|
16
|
+
@target.send :define_attribute_methods, attributes
|
16
17
|
@target.rip_attributes[:write].concat(attributes)
|
18
|
+
|
19
|
+
attributes.each do |attribute|
|
20
|
+
define_dirty_tracking attribute
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def define_dirty_tracking(attribute)
|
27
|
+
@target.send(:define_method, "#{attribute}_with_dirty_tracking=") do |value|
|
28
|
+
attribute_will_change!(attribute) unless send(attribute) == value
|
29
|
+
send("#{attribute}_without_dirty_tracking=", value)
|
30
|
+
end
|
31
|
+
|
32
|
+
@target.send(:alias_method, "#{attribute}_without_dirty_tracking=", "#{attribute}=")
|
33
|
+
@target.send(:alias_method, "#{attribute}=", "#{attribute}_with_dirty_tracking=")
|
17
34
|
end
|
18
35
|
end
|
19
36
|
end
|
data/lib/rest_in_peace.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
+
|
1
3
|
require 'rest_in_peace/definition_proxy'
|
2
4
|
|
3
5
|
module RESTinPeace
|
4
6
|
|
5
7
|
def self.included(base)
|
6
8
|
base.send :extend, ClassMethods
|
9
|
+
base.send :include, ActiveModel::Dirty
|
7
10
|
end
|
8
11
|
|
9
12
|
def api
|
@@ -16,9 +19,9 @@ module RESTinPeace
|
|
16
19
|
|
17
20
|
def hash_for_updates
|
18
21
|
hash_representation = { id: id }
|
19
|
-
|
22
|
+
changed.each do |key|
|
20
23
|
value = send(key)
|
21
|
-
hash_representation[key] = hash_representation_of_object(value)
|
24
|
+
hash_representation[key.to_sym] = hash_representation_of_object(value)
|
22
25
|
end
|
23
26
|
if self.class.rip_namespace
|
24
27
|
{ id: id, self.class.rip_namespace => hash_representation }
|
@@ -27,6 +30,18 @@ module RESTinPeace
|
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
33
|
+
def clear_changes
|
34
|
+
case
|
35
|
+
when respond_to?(:clear_changes_information) # ActiveModel >= 4.2
|
36
|
+
clear_changes_information
|
37
|
+
when respond_to?(:reset_changes) # ActiveModel >= 4.0 && <= 4.1
|
38
|
+
reset_changes
|
39
|
+
else # ActiveModel <= 3.2
|
40
|
+
return unless @changed_attributes
|
41
|
+
@changed_attributes.clear
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
30
45
|
def update_attributes(attributes)
|
31
46
|
attributes.each do |key, value|
|
32
47
|
next unless respond_to?("#{key}=")
|
@@ -51,6 +66,7 @@ module RESTinPeace
|
|
51
66
|
instance_variable_set("@#{key}", value)
|
52
67
|
end
|
53
68
|
end
|
69
|
+
clear_changes
|
54
70
|
end
|
55
71
|
|
56
72
|
def hash_representation_of_object(object)
|
@@ -99,27 +99,6 @@ describe RESTinPeace do
|
|
99
99
|
allow(api_double).to receive(:post).and_return(response)
|
100
100
|
end
|
101
101
|
|
102
|
-
describe '#changed?' do
|
103
|
-
context 'a new instance' do
|
104
|
-
specify { expect(instance.changed?).to eq(false) }
|
105
|
-
end
|
106
|
-
|
107
|
-
context 'a modified instance' do
|
108
|
-
before do
|
109
|
-
instance.description = 'new value'
|
110
|
-
end
|
111
|
-
specify { expect(instance.changed?).to eq(true) }
|
112
|
-
end
|
113
|
-
|
114
|
-
context 'a saved instance' do
|
115
|
-
before do
|
116
|
-
instance.description = 'new value'
|
117
|
-
instance.save
|
118
|
-
end
|
119
|
-
specify { expect(instance.changed?).to eq(false) }
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
102
|
describe 'attribute methods' do
|
124
103
|
specify { expect(instance).to respond_to(:description_changed?) }
|
125
104
|
specify { expect(instance).to respond_to(:title_changed?) }
|
data/spec/rest_in_peace_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe RESTinPeace do
|
|
9
9
|
rest_in_peace do
|
10
10
|
attributes do
|
11
11
|
read :id, :name, :relation
|
12
|
-
write :my_array, :my_hash, :array_with_hash, :overridden_attribute
|
12
|
+
write :my_array, :my_hash, :array_with_hash, :overridden_attribute, :description
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -31,6 +31,7 @@ describe RESTinPeace do
|
|
31
31
|
let(:my_hash) { { element1: 'yolo' } }
|
32
32
|
let(:array_with_hash) { [my_hash.dup] }
|
33
33
|
let(:overridden_attribute) { 'initial value' }
|
34
|
+
let(:description) { 'old description' }
|
34
35
|
let(:attributes) do
|
35
36
|
{
|
36
37
|
id: 1,
|
@@ -40,6 +41,7 @@ describe RESTinPeace do
|
|
40
41
|
my_hash: my_hash,
|
41
42
|
array_with_hash: array_with_hash,
|
42
43
|
overridden_attribute: overridden_attribute,
|
44
|
+
description: description,
|
43
45
|
}
|
44
46
|
end
|
45
47
|
let(:instance) { extended_class.new(attributes) }
|
@@ -75,8 +77,8 @@ describe RESTinPeace do
|
|
75
77
|
specify { expect(extended_class).to respond_to(:rip_attributes) }
|
76
78
|
specify do
|
77
79
|
expect(extended_class.rip_attributes).to eq(
|
78
|
-
read: [:id, :name, :relation, :my_array, :my_hash, :array_with_hash, :overridden_attribute],
|
79
|
-
write: [:my_array, :my_hash, :array_with_hash, :overridden_attribute])
|
80
|
+
read: [:id, :name, :relation, :my_array, :my_hash, :array_with_hash, :overridden_attribute, :description],
|
81
|
+
write: [:my_array, :my_hash, :array_with_hash, :overridden_attribute, :description])
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
@@ -110,6 +112,9 @@ describe RESTinPeace do
|
|
110
112
|
end
|
111
113
|
|
112
114
|
context 'overridden getter' do
|
115
|
+
before do
|
116
|
+
subject.overridden_attribute = 'new value'
|
117
|
+
end
|
113
118
|
specify { expect(subject.hash_for_updates).to include(overridden_attribute: 'something else') }
|
114
119
|
end
|
115
120
|
|
@@ -119,13 +124,22 @@ describe RESTinPeace do
|
|
119
124
|
end
|
120
125
|
|
121
126
|
context 'hash' do
|
122
|
-
|
127
|
+
before do
|
128
|
+
subject.my_hash = { element1: 'swag' }
|
129
|
+
end
|
130
|
+
|
131
|
+
specify { expect(subject.hash_for_updates[:my_hash]).to eq(element1: 'swag') }
|
123
132
|
end
|
124
133
|
|
125
134
|
context 'with objects assigned' do
|
126
|
-
let(:
|
135
|
+
let(:new_hash) { double('OtherClass') }
|
136
|
+
|
137
|
+
before do
|
138
|
+
subject.my_hash = new_hash
|
139
|
+
end
|
140
|
+
|
127
141
|
it 'deeply calls hash_for_updates' do
|
128
|
-
expect(
|
142
|
+
expect(new_hash).to receive(:hash_for_updates).and_return({})
|
129
143
|
subject.hash_for_updates
|
130
144
|
end
|
131
145
|
end
|
@@ -139,7 +153,7 @@ describe RESTinPeace do
|
|
139
153
|
rest_in_peace do
|
140
154
|
attributes do
|
141
155
|
read :id
|
142
|
-
write :name
|
156
|
+
write :name, :description
|
143
157
|
end
|
144
158
|
|
145
159
|
namespace_attributes_with :blubb
|
@@ -147,7 +161,11 @@ describe RESTinPeace do
|
|
147
161
|
end
|
148
162
|
end
|
149
163
|
|
150
|
-
|
164
|
+
before do
|
165
|
+
subject.name = 'new value'
|
166
|
+
end
|
167
|
+
|
168
|
+
specify { expect(subject.hash_for_updates).to eq(id: 1, blubb: { id: 1, name: 'new value' }) }
|
151
169
|
end
|
152
170
|
end
|
153
171
|
|
@@ -204,4 +222,27 @@ describe RESTinPeace do
|
|
204
222
|
to_not change(instance, :name).from(attributes[:name])
|
205
223
|
end
|
206
224
|
end
|
225
|
+
|
226
|
+
describe '#changed?' do
|
227
|
+
subject { instance }
|
228
|
+
|
229
|
+
context 'a new instance' do
|
230
|
+
it { is_expected.to_not be_changed }
|
231
|
+
end
|
232
|
+
|
233
|
+
context 'a modified instance' do
|
234
|
+
before do
|
235
|
+
instance.description = 'new value'
|
236
|
+
end
|
237
|
+
it { is_expected.to be_changed }
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'a saved instance' do
|
241
|
+
before do
|
242
|
+
instance.description = 'new value'
|
243
|
+
instance.clear_changes
|
244
|
+
end
|
245
|
+
it { is_expected.to_not be_changed }
|
246
|
+
end
|
247
|
+
end
|
207
248
|
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-in-peace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Raffael Schmid
|
@@ -13,6 +14,7 @@ dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activemodel
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -23,6 +25,7 @@ dependencies:
|
|
23
25
|
type: :runtime
|
24
26
|
prerelease: false
|
25
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
26
29
|
requirements:
|
27
30
|
- - ! '>='
|
28
31
|
- !ruby/object:Gem::Version
|
@@ -33,6 +36,7 @@ dependencies:
|
|
33
36
|
- !ruby/object:Gem::Dependency
|
34
37
|
name: rake
|
35
38
|
requirement: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
36
40
|
requirements:
|
37
41
|
- - ~>
|
38
42
|
- !ruby/object:Gem::Version
|
@@ -40,6 +44,7 @@ dependencies:
|
|
40
44
|
type: :development
|
41
45
|
prerelease: false
|
42
46
|
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
43
48
|
requirements:
|
44
49
|
- - ~>
|
45
50
|
- !ruby/object:Gem::Version
|
@@ -47,6 +52,7 @@ dependencies:
|
|
47
52
|
- !ruby/object:Gem::Dependency
|
48
53
|
name: rspec
|
49
54
|
requirement: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
50
56
|
requirements:
|
51
57
|
- - ~>
|
52
58
|
- !ruby/object:Gem::Version
|
@@ -54,6 +60,7 @@ dependencies:
|
|
54
60
|
type: :development
|
55
61
|
prerelease: false
|
56
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
57
64
|
requirements:
|
58
65
|
- - ~>
|
59
66
|
- !ruby/object:Gem::Version
|
@@ -61,6 +68,7 @@ dependencies:
|
|
61
68
|
- !ruby/object:Gem::Dependency
|
62
69
|
name: guard
|
63
70
|
requirement: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
64
72
|
requirements:
|
65
73
|
- - ~>
|
66
74
|
- !ruby/object:Gem::Version
|
@@ -71,6 +79,7 @@ dependencies:
|
|
71
79
|
type: :development
|
72
80
|
prerelease: false
|
73
81
|
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
74
83
|
requirements:
|
75
84
|
- - ~>
|
76
85
|
- !ruby/object:Gem::Version
|
@@ -81,6 +90,7 @@ dependencies:
|
|
81
90
|
- !ruby/object:Gem::Dependency
|
82
91
|
name: guard-rspec
|
83
92
|
requirement: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
84
94
|
requirements:
|
85
95
|
- - ~>
|
86
96
|
- !ruby/object:Gem::Version
|
@@ -91,6 +101,7 @@ dependencies:
|
|
91
101
|
type: :development
|
92
102
|
prerelease: false
|
93
103
|
version_requirements: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
94
105
|
requirements:
|
95
106
|
- - ~>
|
96
107
|
- !ruby/object:Gem::Version
|
@@ -101,6 +112,7 @@ dependencies:
|
|
101
112
|
- !ruby/object:Gem::Dependency
|
102
113
|
name: simplecov
|
103
114
|
requirement: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
104
116
|
requirements:
|
105
117
|
- - ~>
|
106
118
|
- !ruby/object:Gem::Version
|
@@ -111,6 +123,7 @@ dependencies:
|
|
111
123
|
type: :development
|
112
124
|
prerelease: false
|
113
125
|
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
114
127
|
requirements:
|
115
128
|
- - ~>
|
116
129
|
- !ruby/object:Gem::Version
|
@@ -137,6 +150,10 @@ files:
|
|
137
150
|
- Rakefile
|
138
151
|
- VERSION
|
139
152
|
- examples/pagination_with_headers.rb
|
153
|
+
- gemfiles/Gemfile.rails-3.2.x
|
154
|
+
- gemfiles/Gemfile.rails-4.0.x
|
155
|
+
- gemfiles/Gemfile.rails-4.1.x
|
156
|
+
- gemfiles/Gemfile.rails-4.2.x
|
140
157
|
- images/rest_in_peace.gif
|
141
158
|
- lib/rest-in-peace.rb
|
142
159
|
- lib/rest_in_peace.rb
|
@@ -165,26 +182,27 @@ files:
|
|
165
182
|
homepage: http://github.com/ninech/
|
166
183
|
licenses:
|
167
184
|
- MIT
|
168
|
-
metadata: {}
|
169
185
|
post_install_message:
|
170
186
|
rdoc_options: []
|
171
187
|
require_paths:
|
172
188
|
- lib
|
173
189
|
required_ruby_version: !ruby/object:Gem::Requirement
|
190
|
+
none: false
|
174
191
|
requirements:
|
175
192
|
- - ! '>='
|
176
193
|
- !ruby/object:Gem::Version
|
177
194
|
version: '0'
|
178
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
+
none: false
|
179
197
|
requirements:
|
180
198
|
- - ! '>='
|
181
199
|
- !ruby/object:Gem::Version
|
182
200
|
version: '0'
|
183
201
|
requirements: []
|
184
202
|
rubyforge_project:
|
185
|
-
rubygems_version:
|
203
|
+
rubygems_version: 1.8.23.2
|
186
204
|
signing_key:
|
187
|
-
specification_version:
|
205
|
+
specification_version: 3
|
188
206
|
summary: REST in peace
|
189
207
|
test_files:
|
190
208
|
- spec/rest_in_peace/active_model_api_spec.rb
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
MzVkMWFiODFlNGQ2ZTVkMTM0MTRkYTg1OGRmNjBmYWI1NGM3YWNmYw==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZWZlYjY3NjNkNzQwNjcwOGVlZmU5YzVjZTM2YjBlNjk3YTA2ZTY1Yw==
|
7
|
-
SHA512:
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
ZDRkZjlmY2NlNGU4MDgzM2UyY2ZmZTc5NmQxOWZiMTcxYTdjZTBiN2Y0NTc5
|
10
|
-
MTg1ZDY5YzA2NDFjNjNkNzFiOWZhZmUyZDBhMGVjNWQxYzNjZGVkZDJiNzRj
|
11
|
-
YjM2ODBkNDA3NWFkZmU3NWViZmVkNWU1Y2Q0MDQyYmVlYjM1MmY=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZjY1MjExMjJlNGU1MDEzYzEwMzgyZTY3MmQ3ZGNkZDI5NWM2OWM2M2VkYmQ4
|
14
|
-
NTU1NzY3MmE5N2JlODIyODYxM2ZmNjdhYTk3YWNhMmUzMWRhOTc4MWZkODYx
|
15
|
-
YmYwMTcyMGUxOTg3YTRmYjRkYTcyYjRhYjIwMmFjMTU1Mjg3MjA=
|