ncore 3.7.1 → 3.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c6562d9f0e6fca58cc5ad061d9461006dc509f92e960a55ed83bd127fd1d503
4
- data.tar.gz: f61859177171d285d7442dfdee1a66964b318bb14824b7e409da2e3e27b92e0d
3
+ metadata.gz: 5c93d49d552806a8439994a201a54ae1550be771c5ba3e855131317267492efb
4
+ data.tar.gz: a20b77b20173293816a3a2f753561b3cfc0a962644db0696f4a2f5d7dedf024d
5
5
  SHA512:
6
- metadata.gz: 2b702ea0bc616e2aabbd685ac53579759e59176865e562f383aff61682f3cb6defc5aa177ec398a0a9b18229bd8f5a78d5fc5e390f61ce722998e5301bd7dfa1
7
- data.tar.gz: e2ab8234b5fc0358ba38f2460065dfe029ee92d59d575dbb7f35c9d5b8edb71aff8d15fb0278a50678401a71bea55705eb12bda756e4c99295430d45ae16cbee
6
+ metadata.gz: 9ef44487b9cc0def0b5dc9be8f34bac4a13ae3fd1226f5e2d87d1a02cc111d52565a142a92e7619493b9d236eb68837832b9eee62e6fdae86b0bc2c0cf64d44f
7
+ data.tar.gz: 9337020d9f962ef43852d859981fa2f67a198fd51f6ad3ced23ecbc4aeafea6ff4b67b651abf41e0868ede636490383dd4e7746c2607ed0bf4b4f01c9c03ab0f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ #### 3.8.0
2
+
3
+ - Add has_one association helper
4
+ - Make belongs_to return existing data even when association_key is blank
5
+ - Make reload() public for singleton resources
6
+ - Optimize calling some_attr?() by defining such methods directly.
7
+ Previously these calls went through method_missing.
8
+
1
9
  #### 3.7.1
2
10
 
3
11
  - Don't send both mixed and lowercase headers for accept, user-agent
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2023 Notioneer, Inc.
1
+ Copyright (c) 2014-2024 Notioneer, Inc.
2
2
 
3
3
  MIT License
4
4
 
@@ -1,6 +1,89 @@
1
1
  module NCore
2
2
  module Associations
3
3
 
4
+ # assoc_name - singular association name
5
+ # :association_key - key used by the association to reference the parent
6
+ # defaults to `attrib_name+'_id'`
7
+ # :class_name - Module::Class of the child association, as a string
8
+ def has_one(assoc_name, association_key: nil, class_name: nil)
9
+ assoc_name = assoc_name.to_s
10
+ parent_key = association_key&.to_s || "#{attrib_name}_id"
11
+ klass = class_name || "#{module_name}::#{assoc_name.camelize}"
12
+
13
+ # def item({})
14
+ class_eval <<-A1, __FILE__, __LINE__+1
15
+ def #{assoc_name}(params={})
16
+ return nil unless id
17
+ reload = params.delete :reload
18
+ cacheable = params.except(:credentials, :request).empty?
19
+ params = parse_request_params(params).reverse_merge credentials: api_creds
20
+ params[:#{parent_key}] = id
21
+ if cacheable
22
+ # only cache unfiltered, default api call
23
+ @attribs[:#{assoc_name}] = (!reload && @attribs[:#{assoc_name}]) || #{klass}.first(params)
24
+ else
25
+ #{klass}.first(params)
26
+ end
27
+ end
28
+ A1
29
+
30
+ # def create_item({})
31
+ # will always return the object; check .errors? or .valid? to see how it went
32
+ class_eval <<-C1, __FILE__, __LINE__+1
33
+ def create_#{assoc_name}(params={})
34
+ raise UnsavedObjectError unless id
35
+ params = parse_request_params(params).reverse_merge credentials: api_creds
36
+ params[:#{parent_key}] = id
37
+ #{klass}.create(params)
38
+ end
39
+ C1
40
+
41
+ # def create_item!({})
42
+ class_eval <<-C2, __FILE__, __LINE__+1
43
+ def create_#{assoc_name}!(params={})
44
+ raise UnsavedObjectError unless id
45
+ params = parse_request_params(params).reverse_merge credentials: api_creds
46
+ params[:#{parent_key}] = id
47
+ #{klass}.create!(params)
48
+ end
49
+ C2
50
+
51
+ # def update_item({})
52
+ # will always return the object; check .errors? or .valid? to see how it went
53
+ class_eval <<-U1, __FILE__, __LINE__+1
54
+ def update_#{assoc_name}(params={})
55
+ raise UnsavedObjectError unless id
56
+ #{assoc_name}.update(params)
57
+ end
58
+ U1
59
+
60
+ # def update_item!({})
61
+ class_eval <<-U2, __FILE__, __LINE__+1
62
+ def update_#{assoc_name}!(params={})
63
+ raise UnsavedObjectError unless id
64
+ #{assoc_name}.update!(params)
65
+ end
66
+ U2
67
+
68
+ # def delete_item({})
69
+ # will always return the object; check .errors? or .valid? to see how it went
70
+ class_eval <<-D1, __FILE__, __LINE__+1
71
+ def delete_#{assoc_name}(params={})
72
+ raise UnsavedObjectError unless id
73
+ #{assoc_name}.delete(params)
74
+ end
75
+ D1
76
+
77
+ # def delete_item!({})
78
+ class_eval <<-D2, __FILE__, __LINE__+1
79
+ def delete_#{assoc_name}!(params={})
80
+ raise UnsavedObjectError unless id
81
+ #{assoc_name}.delete!(params)
82
+ end
83
+ D2
84
+ end
85
+
86
+
4
87
  # assoc_name - plural association name
5
88
  # :association_key - key used by the association to reference the parent
6
89
  # defaults to `attrib_name+'_id'`
@@ -111,6 +194,7 @@ module NCore
111
194
  D2
112
195
  end
113
196
 
197
+
114
198
  # assoc_name - singular association name
115
199
  # :association_key - key on this resource used to reference the parent association
116
200
  # defaults to `assoc_name+'_id'`
@@ -125,12 +209,14 @@ module NCore
125
209
  class_eval <<-P1, __FILE__, __LINE__+1
126
210
  attr :#{parent_key}
127
211
  def #{assoc_name}(params={})
128
- return nil unless #{parent_key}
212
+ reload = params.delete :reload
129
213
  params = parse_request_params(params).reverse_merge credentials: api_creds
130
214
  if params.except(:credentials, :request).empty?
131
215
  # only cache unfiltered, default api call
132
- @attribs[:#{assoc_name}] ||= #{klass}.find(#{parent_key}, params)
216
+ @attribs[:#{assoc_name}] = nil if reload
217
+ @attribs[:#{assoc_name}] ||= #{parent_key} && #{klass}.find(#{parent_key}, params)
133
218
  else
219
+ return nil unless #{parent_key}
134
220
  #{klass}.find(#{parent_key}, params)
135
221
  end
136
222
  end
@@ -8,6 +8,9 @@ module NCore
8
8
 
9
9
 
10
10
  module ClassMethods
11
+ # attr(:name, ...)
12
+ # adds: obj.name => raw json type
13
+ # obj.name? => bool
11
14
  def attr(*attrs)
12
15
  attrs.each do |attr|
13
16
  check_existing_method(attr)
@@ -15,10 +18,17 @@ module NCore
15
18
  def #{attr}
16
19
  self[:#{attr}]
17
20
  end
21
+
22
+ def #{attr}?
23
+ !! self[:#{attr}]
24
+ end
18
25
  AR
19
26
  end
20
27
  end
21
28
 
29
+ # attr_datetime(:updated_at, ...)
30
+ # adds: obj.updated_at => Time, or raw json type if not parseable
31
+ # obj.updated_at? => bool
22
32
  def attr_datetime(*attrs)
23
33
  attrs.each do |attr|
24
34
  check_existing_method(attr)
@@ -35,10 +45,17 @@ module NCore
35
45
  rescue ArgumentError, TypeError
36
46
  self[:#{attr}]
37
47
  end
48
+
49
+ def #{attr}?
50
+ !! self[:#{attr}]
51
+ end
38
52
  AD
39
53
  end
40
54
  end
41
55
 
56
+ # attr_decimal(:amount, ...)
57
+ # adds: obj.amount => BigMoney if String, else raw json type
58
+ # obj.amount? => bool
42
59
  def attr_decimal(*attrs)
43
60
  attrs.each do |attr|
44
61
  check_existing_method(attr)
@@ -51,6 +68,10 @@ module NCore
51
68
  self[:#{attr}]
52
69
  end
53
70
  end
71
+
72
+ def #{attr}?
73
+ !! self[:#{attr}]
74
+ end
54
75
  AD
55
76
  end
56
77
  end
@@ -19,8 +19,6 @@ module NCore
19
19
  'singleton'
20
20
  end
21
21
 
22
- private
23
-
24
22
  def reload(find_params={})
25
23
  params = parse_request_params(find_params).reverse_merge credentials: api_creds
26
24
  parsed, @api_creds = request(:get, resource_path, params)
data/lib/ncore/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module NCore
2
- VERSION = '3.7.1'
2
+ VERSION = '3.8.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ncore
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.1
4
+ version: 3.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Notioneer Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-27 00:00:00.000000000 Z
11
+ date: 2024-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel