flexirest 1.10.0 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f713d7d9f8f37de42e54bd20623b4477b9893b6cd40f0d2d5e8c5a06079a821
4
- data.tar.gz: b5fc1fe7bffbe57a6adf9443aab86d91313fddd90b2fcc2ef35f50f2b41ec942
3
+ metadata.gz: 89ef0bd6a927d830d9f98f1e4deeee8d26bf68a203a001f2299785386e1365b9
4
+ data.tar.gz: 3fa35c87cb16df1181207a6393682c6ec003346b4789d8bff30bbedbdba0e753
5
5
  SHA512:
6
- metadata.gz: eedfb75a0ecacbb1114d62fad201cf5e478242dd74126b87b29f1081e9c56b4194b600c6d729ac8afa70a7dd4ee8d66a03057974a2e52ee76f575e848027bfca
7
- data.tar.gz: 955f229836e2e6fbc6273b1505294619ab0a614af05e79d0e5113b956959dbf22bb76ed23b2a169a9dafe207b6ab48b3559f7adeb84f22e3fcff01fbc223b28f
6
+ metadata.gz: 520a9f3131d517c00180dd15a9fbd8c03372343bde13474457a37db78b321efa54a756878bd5161253ab6646a6e6ffc24171a3f69fca043c14cfb49630cf7ef8
7
+ data.tar.gz: 5580fe4c1079b03fb51465550afce7ca4a542051efbd127df0405d113d47955182d88cfc324ff184a36be7eee0d4eaab5fad85efe47f94d5163846aad952df6d
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.10.1
4
+
5
+ Enhancement:
6
+
7
+ - Nested objects now report their dirty/changed status up to the parent (thanks to Matthias Hähnel for the bug report)
8
+
3
9
  ## 1.10.0
4
10
 
5
11
  Enhancement:
@@ -66,6 +66,7 @@ After callbacks work in exactly the same way:
66
66
  ```ruby
67
67
  class Person < Flexirest::Base
68
68
  get :all, "/people"
69
+ get :all, "/people"
69
70
 
70
71
  after_request :fix_empty_content
71
72
  after_request :cache_all_people
@@ -88,6 +89,32 @@ end
88
89
 
89
90
  **Note:** since v1.3.21 the empty response trick above isn't necessary, empty responses for 204 are accepted normally (the method returns `true`), but this is here to show an example of an `after_request` callback adjusting the body. The `cache_all_people` example shows how to cache a response even if the server doesn't send the correct headers.
90
91
 
92
+ If you manually set caching responses like the above, you may want to invalidate that cache when you make a create, update, delete etc request for the resource, for example:
93
+
94
+ ```ruby
95
+ class Animal < Flexirest::Base
96
+ after_request :cache
97
+ before_request :cache_cleanup
98
+
99
+ get :get, '/animals/:id'
100
+ post :update, '/animals/:id'
101
+ delete :delete, '/animals/:id'
102
+
103
+ def cache_cleanup(name, request)
104
+ if name == :update || name == :delete
105
+ Flexirest::Logger.info(" \033[1;4;32m#{Flexirest.name}\033[0m Invalidating cache for #{self.class.name} #{request.url}")
106
+ Rails.cache.delete("#{self.class.name}:#{request.url}")
107
+ end
108
+ end
109
+
110
+ def cache(name, response)
111
+ if name == :get
112
+ response.response_headers["Expires"] = 1.hour.from_now.iso8601
113
+ end
114
+ end
115
+ end
116
+ ```
117
+
91
118
  If you want to trap an error in an `after_request` callback and retry the request, this can be done - but retries will only happen once for each request (so we'd recommend checking all conditions in a single `after_request` and then retrying after fixing them all). You achieve this by raising a `Flexirest::CallbackRetryRequestException` from the callback.
92
119
 
93
120
  ```ruby
@@ -100,7 +127,7 @@ class Person < Flexirest::Base
100
127
 
101
128
  def fix_invalid_request(name, response)
102
129
  if response.status == 401
103
- # Do something to fix the state of caches/variables used in the
130
+ # Do something to fix the state of caches/variables used in the
104
131
  # before_request, etc
105
132
  raise Flexirest::CallbackRetryRequestException.new
106
133
  end
@@ -11,6 +11,8 @@ module Flexirest
11
11
  attr_accessor :_status
12
12
  attr_accessor :_etag
13
13
  attr_accessor :_headers
14
+ attr_accessor :_parent
15
+ attr_accessor :_parent_attribute_name
14
16
 
15
17
  instance_methods.each do |m|
16
18
  next unless %w{display presence load require untrust trust freeze method enable_warnings with_warnings suppress capture silence quietly debugger breakpoint}.map(&:to_sym).include? m
@@ -41,6 +43,13 @@ module Flexirest
41
43
  def _copy_from(result)
42
44
  @attributes = result._attributes
43
45
  @_status = result._status
46
+ self._parent = result._parent
47
+ self._parent_attribute_name = result._parent_attribute_name
48
+ @attributes.each do |k,v|
49
+ if v.respond_to?(:_parent) && v._parent.present?
50
+ @attributes[k]._parent = self
51
+ end
52
+ end
44
53
  _clean!
45
54
  end
46
55
 
@@ -184,6 +193,10 @@ module Flexirest
184
193
  output.to_json
185
194
  end
186
195
 
196
+ def _set_dirty(key)
197
+ @dirty_attributes[key.to_sym] = true
198
+ end
199
+
187
200
  private
188
201
 
189
202
  def _set_attribute(key, value)
@@ -191,6 +204,9 @@ module Flexirest
191
204
  old_value = @attributes[key.to_sym] unless old_value
192
205
  old_value = old_value[0] if old_value and old_value.is_a? Array
193
206
  @dirty_attributes[key.to_sym] = [old_value, value] if old_value != value
207
+ if _parent
208
+ _parent._set_dirty(_parent_attribute_name)
209
+ end
194
210
  @attributes[key.to_sym] = value
195
211
  end
196
212
 
@@ -94,6 +94,10 @@ module Flexirest
94
94
  request = Flexirest::Request.new(method, @request.object)
95
95
  request.url = request.forced_url = @url
96
96
  @object = request.call
97
+ if @object.respond_to?(:_parent=)
98
+ @object._parent = @options[:parent]
99
+ @object._parent_attribute_name = @options[:parent_attribute_name]
100
+ end
97
101
  end
98
102
  end
99
103
  end
@@ -651,7 +651,7 @@ module Flexirest
651
651
  result
652
652
  end
653
653
 
654
- def new_object(attributes, name = nil)
654
+ def new_object(attributes, name = nil, parent = nil, parent_attribute_name = nil)
655
655
  @method[:options][:has_many] ||= {}
656
656
  name = name.to_sym rescue nil
657
657
  if @method[:options][:has_many][name]
@@ -664,6 +664,9 @@ module Flexirest
664
664
  object = create_object_instance
665
665
  end
666
666
 
667
+ object._parent = parent
668
+ object._parent_attribute_name = parent_attribute_name
669
+
667
670
  if hal_response? && name.nil?
668
671
  attributes = handle_hal_links_embedded(object, attributes)
669
672
  end
@@ -691,9 +694,9 @@ module Flexirest
691
694
  v = value
692
695
  assignable_hash = value_from_object ? object._attributes : {}
693
696
  if value_from_object && @method[:options][:lazy].include?(k)
694
- assignable_hash[k] = Flexirest::LazyAssociationLoader.new(overridden_name, v, self, overridden_name:(overridden_name))
697
+ assignable_hash[k] = Flexirest::LazyAssociationLoader.new(overridden_name, v, self, overridden_name:(overridden_name), parent: object, parent_attribute_name: k)
695
698
  elsif v.is_a? Hash
696
- assignable_hash[k] = new_object(v, overridden_name )
699
+ assignable_hash[k] = new_object(v, overridden_name, object, k)
697
700
  elsif v.is_a? Array
698
701
  if @method[:options][:array].include?(k)
699
702
  assignable_hash[k] = Array.new
@@ -4,6 +4,8 @@ module Flexirest
4
4
 
5
5
  attr_accessor :_status, :items
6
6
  attr_reader :_headers
7
+ attr_accessor :_parent
8
+ attr_accessor :_parent_attribute_name
7
9
 
8
10
  def initialize(response = nil)
9
11
  @_status = response.try :status
@@ -1,3 +1,3 @@
1
1
  module Flexirest
2
- VERSION = "1.10.0"
2
+ VERSION = "1.10.1"
3
3
  end
@@ -12,6 +12,11 @@ class TranslatorExample
12
12
  end
13
13
  end
14
14
 
15
+ class NestedExample < Flexirest::BaseWithoutValidation
16
+ get :all, "/all", fake:"{\"person\":{\"name\": \"Billy\"}}"
17
+ end
18
+
19
+
15
20
  class AlteringClientExample < Flexirest::BaseWithoutValidation
16
21
  translator TranslatorExample
17
22
  base_url "http://www.example.com"
@@ -140,6 +145,31 @@ describe Flexirest::BaseWithoutValidation do
140
145
  expect(client).to be_dirty
141
146
  end
142
147
 
148
+ it "should store attribute changes on nested objects and mark them as dirty in the parent" do
149
+ client = NestedExample.all
150
+ client.person.name = "John"
151
+ expect(client.person.name.to_s).to eq("John")
152
+
153
+ expect(client).to be_dirty
154
+ expect(client.changes.keys).to include(:person)
155
+
156
+ expect(client.person).to be_dirty
157
+ expect(client.person.changes.keys).to include(:name)
158
+ end
159
+
160
+ it "should store attribute changes on nested objects loaded via instance methods and mark them as dirty in the parent" do
161
+ client = NestedExample.new()
162
+ client.all
163
+ client.person.name = "John"
164
+ expect(client.person.name.to_s).to eq("John")
165
+
166
+ expect(client).to be_dirty
167
+ expect(client.changes.keys).to include(:person)
168
+
169
+ expect(client.person).to be_dirty
170
+ expect(client.person.changes.keys).to include(:name)
171
+ end
172
+
143
173
  it "should track changed attributes and provide access to previous values (similar to ActiveRecord/Mongoid)" do
144
174
  client = EmptyExample.new()
145
175
  client["test"] = "Something"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flexirest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jeffries
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-26 00:00:00.000000000 Z
11
+ date: 2020-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler