flexirest 1.10.0 → 1.10.1

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 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