foobara 0.0.48 → 0.0.50

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: 7c661c32185af433ba2355ce71bf37524893d00901a6e885ab5bd874339e48b6
4
- data.tar.gz: 8ab10b8b9191bc81548d07269ca8c4906515164aa87a702ac7b944170e2420a7
3
+ metadata.gz: 046fdc3bab52559499e744edbde0ef847e26c4e6107423779351a26acc654619
4
+ data.tar.gz: 56174a565dafcdf3cd03a66e791be3d5a6074bd426c203371b6d7f41fa3a7e12
5
5
  SHA512:
6
- metadata.gz: 3aaff8aa022ea5cf95ab300430576fbf08d813ccd2344630b035bf54372826fda4de76e5b7d9937e70278fcc7b0c23973d4499be25ad1531401b8b82004c153a
7
- data.tar.gz: ffbc1887647b08588f218798cb99ab27af30ece05d4540926cb521a429c3dc9a4d992163802528f9f3a8022a52558e5158ee4b5b13dbe297a2e6036393ec49dd
6
+ metadata.gz: ca08c711d53d11eb7ee073d040163df8bfe23c69b4b8e4c4f9647c6d216578755388b009b6d67e2cf988cc4e043413bfbe8f4f78ecb7690f713191cf00474255
7
+ data.tar.gz: a3b1e726a7295d1a0e4d22ef8f7a8130b39d57a1576f07f3f36bb20347ffce4bde07d6205c9c2853b392f47542ef7c696de57ab02c7c11d463484e3f5eebc779
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.0.50] - 2025-01-22
2
+
3
+ - Fill out more foobara_ model attribute helper methods to further support the ActiveRecordType gem
4
+
1
5
  ## [0.0.48] - 2025-01-17
2
6
 
3
7
  - Add support for foobara_attributes_type to allow ActiveRecordType gem to work
@@ -25,7 +25,11 @@ module Foobara
25
25
  end
26
26
  end
27
27
 
28
- rawish_type_declaration[:defaults] = defaults unless defaults.empty?
28
+ if defaults.empty?
29
+ rawish_type_declaration.delete(:defaults)
30
+ else
31
+ rawish_type_declaration[:defaults] = defaults
32
+ end
29
33
 
30
34
  rawish_type_declaration
31
35
  end
@@ -40,7 +40,11 @@ module Foobara
40
40
  end
41
41
  end
42
42
 
43
- rawish_type_declaration[:required] = required_attributes unless required_attributes.empty?
43
+ if required_attributes.empty?
44
+ rawish_type_declaration.delete(:required)
45
+ else
46
+ rawish_type_declaration[:required] = required_attributes
47
+ end
44
48
 
45
49
  rawish_type_declaration
46
50
  end
@@ -25,6 +25,16 @@ module Foobara
25
25
  @inputs_type
26
26
  end
27
27
 
28
+ def add_inputs(...)
29
+ new_type = type_for_declaration(...)
30
+ new_declaration = TypeDeclarations::Attributes.merge(
31
+ inputs_type.declaration_data,
32
+ new_type.declaration_data
33
+ )
34
+
35
+ inputs new_declaration
36
+ end
37
+
28
38
  def inputs_type
29
39
  return @inputs_type if defined?(@inputs_type)
30
40
 
@@ -5,10 +5,12 @@ module Foobara
5
5
  include Concern
6
6
 
7
7
  module ClassMethods
8
- def associations
9
- @associations ||= construct_associations
8
+ def foobara_associations
9
+ @foobara_associations ||= construct_associations
10
10
  end
11
11
 
12
+ alias associations foobara_associations
13
+
12
14
  def deep_associations
13
15
  @deep_associations ||= begin
14
16
  deep = {}
@@ -20,18 +20,20 @@ module Foobara
20
20
  # :nocov:
21
21
  end
22
22
 
23
- @primary_key_attribute = attribute_name.to_sym
23
+ @foobara_primary_key_attribute = attribute_name.to_sym
24
24
 
25
25
  set_model_type
26
26
  end
27
27
 
28
- def primary_key_attribute
29
- return @primary_key_attribute if @primary_key_attribute
28
+ def foobara_primary_key_attribute
29
+ return @foobara_primary_key_attribute if @foobara_primary_key_attribute
30
30
 
31
31
  unless superclass == DetachedEntity
32
- @primary_key_attribute = superclass.primary_key_attribute
32
+ @foobara_primary_key_attribute = superclass.primary_key_attribute
33
33
  end
34
34
  end
35
+
36
+ alias primary_key_attribute foobara_primary_key_attribute
35
37
  end
36
38
 
37
39
  def primary_key
@@ -23,10 +23,12 @@ module Foobara
23
23
  end
24
24
  end
25
25
 
26
- def primary_key_type
27
- @primary_key_type ||= attributes_type.element_types[primary_key_attribute]
26
+ def foobara_primary_key_type
27
+ @foobara_primary_key_type ||= attributes_type.element_types[primary_key_attribute]
28
28
  end
29
29
 
30
+ alias primary_key_type foobara_primary_key_type
31
+
30
32
  def full_entity_name
31
33
  full_model_name
32
34
  end
@@ -7,7 +7,6 @@ module Foobara
7
7
  include Concerns::Attributes
8
8
  include Concerns::Persistence
9
9
  include Concerns::Initialization
10
- include Concerns::AttributeHelpers
11
10
  include Concerns::Types
12
11
 
13
12
  class << self
@@ -30,6 +30,7 @@ module Foobara
30
30
  "model",
31
31
  "detached_entity",
32
32
  "entity",
33
+ "model_attribute_helpers",
33
34
  "command",
34
35
  "domain_mapper",
35
36
  "persistence",
@@ -102,7 +102,7 @@ module Foobara
102
102
  )
103
103
  end
104
104
 
105
- def attributes_type
105
+ def foobara_attributes_type
106
106
  return @attributes_type if @attributes_type
107
107
 
108
108
  @attributes_type = if model_type
@@ -112,6 +112,8 @@ module Foobara
112
112
  end
113
113
  end
114
114
 
115
+ alias attributes_type foobara_attributes_type
116
+
115
117
  def model_type=(model_type)
116
118
  @model_type = model_type
117
119
 
@@ -0,0 +1,16 @@
1
+ require "date"
2
+ require "time"
3
+ require "bigdecimal"
4
+
5
+ module Foobara
6
+ module ModelAttributeHelpers
7
+ class << self
8
+ def install!
9
+ Model.include Concerns::AttributeHelpers
10
+ Model.include Concerns::AttributeHelperAliases
11
+ Entity.include Concerns::AttributeHelpers
12
+ Entity.include Concerns::AttributeHelperAliases
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ # This is currently the working file, fix this up/move it
2
+
3
+ module Foobara
4
+ module ModelAttributeHelpers
5
+ module Concerns
6
+ module AttributeHelperAliases
7
+ include Foobara::Concern
8
+
9
+ module ClassMethods
10
+ %i[
11
+ attributes_for_update
12
+ type_from_foobara_model_class
13
+ attributes_type_from_foobara_model_class
14
+ primary_key_attribute_from_foobara_model_class
15
+ foobara_model_class_has_primary_key
16
+ attributes_for_create
17
+ attributes_for_aggregate_update
18
+ attributes_for_atom_update
19
+ attributes_for_find_by
20
+ type_declaration_value_at
21
+ ].each do |method_name|
22
+ define_method method_name do |*args, **opts, &block|
23
+ send("foobara_#{method_name}", *args, **opts, &block)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,143 @@
1
+ # delete this file
2
+
3
+ module Foobara
4
+ module ModelAttributeHelpers
5
+ module Concerns
6
+ # TODO: This concern is retroactively designed to be mixed into any entity-like class that can hold an
7
+ # entity-like foobara type.
8
+ # Because we want a subclass of ActiveRecord::Base to be such a target in the case of the
9
+ # foobara-active-record-type class, but because we can't make ActiveRecord::Base a subclass of Entity or
10
+ # DetachedEntity, and also because it makes sense to extend such behavior to foobara model classes,
11
+ # we will implement this as a Concern/mixin with a published expected interface and prefixed methods.
12
+ # This also means it should live in its own project, not here in the entity project.
13
+ # required methods:
14
+ #
15
+ # foobara_type
16
+ # foobara_attributes_type
17
+ # foobara_primary_key_attribute (nil if not an entity type)
18
+ # foobara_primary_key_type (nil if not an entity type)
19
+ # foobara_associations
20
+ module AttributeHelpers
21
+ include Foobara::Concern
22
+
23
+ module ClassMethods
24
+ def foobara_has_primary_key?
25
+ respond_to?(:foobara_primary_key_attribute)
26
+ end
27
+
28
+ def foobara_attributes_for_update(require_primary_key: false)
29
+ foobara_attributes_for_aggregate_update(require_primary_key:)
30
+ end
31
+
32
+ # TODO: we should have metadata on the entity about whether it required a primary key
33
+ # upon creation or not instead of an option here.
34
+ def foobara_attributes_for_create(includes_primary_key: false)
35
+ return foobara_attributes_type if includes_primary_key
36
+ return foobara_attributes_type unless foobara_has_primary_key?
37
+
38
+ declaration = foobara_attributes_type.declaration_data
39
+
40
+ Foobara::TypeDeclarations::Attributes.reject(declaration, foobara_primary_key_attribute)
41
+ end
42
+
43
+ def foobara_attributes_for_aggregate_update(require_primary_key: false, initial: true)
44
+ declaration = foobara_attributes_type.declaration_data
45
+ declaration = Util.deep_dup(declaration)
46
+
47
+ declaration.delete(:defaults)
48
+ declaration.delete(:required)
49
+
50
+ if initial && foobara_has_primary_key?
51
+ if require_primary_key
52
+ declaration[:required] = [foobara_primary_key_attribute]
53
+ else
54
+ TypeDeclarations::Attributes.reject(declaration, foobara_primary_key_attribute)
55
+ end
56
+ end
57
+
58
+ foobara_associations.each_pair do |data_path, type|
59
+ if type.extends?(BuiltinTypes[:entity])
60
+ target_class = type.target_class
61
+
62
+ entry = foobara_type_declaration_value_at(declaration, DataPath.new(data_path).path)
63
+ entry.clear
64
+ entry.merge!(target_class.foobara_attributes_for_aggregate_update(initial: false))
65
+ end
66
+ end
67
+
68
+ declaration
69
+ end
70
+
71
+ def foobara_attributes_for_atom_update(require_primary_key: false)
72
+ declaration = foobara_attributes_type.declaration_data
73
+ declaration = Util.deep_dup(declaration)
74
+
75
+ declaration.delete(:defaults)
76
+
77
+ if foobara_has_primary_key?
78
+ if require_primary_key
79
+ declaration[:required] = [foobara_primary_key_attribute]
80
+ else
81
+ declaration = TypeDeclarations::Attributes.reject(declaration, foobara_primary_key_attribute)
82
+ end
83
+ end
84
+
85
+ # expect all associations to be expressed as primary key values
86
+ # TODO: should we have a special type for encapsulating primary keys types??
87
+ foobara_associations.each_pair do |data_path, type|
88
+ if type.extends?(BuiltinTypes[:entity])
89
+ target_class = type.target_class
90
+ # TODO: do we really need declaration_data? Why cant we use the type directly?
91
+ # TODO: make this work with the type directly for performance reasons.
92
+ primary_key_type_declaration = target_class.foobara_primary_key_type.declaration_data
93
+ entry = foobara_type_declaration_value_at(declaration, DataPath.new(data_path).path)
94
+ entry.clear
95
+ entry.merge!(primary_key_type_declaration)
96
+ end
97
+ end
98
+
99
+ declaration
100
+ end
101
+
102
+ def foobara_attributes_for_find_by
103
+ element_type_declarations = {}
104
+
105
+ foobara_attributes_type.element_types.each_pair do |attribute_name, attribute_type|
106
+ element_type_declarations[attribute_name] = attribute_type.reference_or_declaration_data
107
+ end
108
+
109
+ handler = Domain.global.foobara_type_builder.handler_for_class(
110
+ TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
111
+ )
112
+
113
+ handler.desugarize(
114
+ type: "::attributes",
115
+ element_type_declarations:
116
+ )
117
+ end
118
+
119
+ private
120
+
121
+ def foobara_type_declaration_value_at(declaration, path_parts)
122
+ return declaration if path_parts.empty?
123
+
124
+ path_part, *path_parts = path_parts
125
+
126
+ declaration = case path_part
127
+ when :"#"
128
+ declaration[:element_type_declaration]
129
+ when Symbol, Integer
130
+ declaration[:element_type_declarations][path_part]
131
+ else
132
+ # :nocov:
133
+ raise "Bad path part #{path_part}"
134
+ # :nocov:
135
+ end
136
+
137
+ foobara_type_declaration_value_at(declaration, path_parts)
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -21,12 +21,55 @@ module Foobara
21
21
  end
22
22
  end
23
23
 
24
- {
24
+ handler = Domain.global.foobara_type_builder.handler_for_class(
25
+ TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
26
+ )
27
+
28
+ handler.desugarize(
25
29
  type: "::attributes",
26
30
  element_type_declarations:,
27
31
  required:,
28
32
  defaults:
29
- }
33
+ )
34
+ end
35
+
36
+ def reject(declaration, *keys)
37
+ declaration = Util.deep_dup(declaration)
38
+
39
+ element_type_declarations = declaration[:element_type_declarations]
40
+ required = declaration[:required]
41
+ defaults = declaration[:defaults]
42
+
43
+ changed = false
44
+
45
+ keys.flatten.each do |key|
46
+ key = key.to_sym
47
+
48
+ if element_type_declarations.key?(key)
49
+ changed = true
50
+ element_type_declarations.delete(key)
51
+ end
52
+
53
+ if required&.include?(key)
54
+ changed = true
55
+ required.delete(key)
56
+ end
57
+
58
+ if defaults&.key?(key)
59
+ changed = true
60
+ defaults.delete(key)
61
+ end
62
+ end
63
+
64
+ if changed
65
+ handler = Domain.global.foobara_type_builder.handler_for_class(
66
+ TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
67
+ )
68
+
69
+ handler.desugarize(declaration)
70
+ else
71
+ declaration
72
+ end
30
73
  end
31
74
  end
32
75
  end
@@ -47,7 +47,6 @@ module Foobara
47
47
 
48
48
  def _to_declaration(&)
49
49
  instance_eval(&)
50
- _prune_type_declaration
51
50
  _type_declaration
52
51
  end
53
52
 
@@ -163,30 +162,20 @@ module Foobara
163
162
  end
164
163
 
165
164
  def _add_to_required(attribute_name)
165
+ _type_declaration[:required] ||= []
166
166
  _type_declaration[:required] << attribute_name.to_sym
167
167
  end
168
168
 
169
169
  def _add_to_defaults(attribute_name, value)
170
+ _type_declaration[:defaults] ||= {}
170
171
  _type_declaration[:defaults][attribute_name.to_sym] = value
171
172
  end
172
173
 
173
- def _prune_type_declaration
174
- if _type_declaration[:required].empty?
175
- _type_declaration.delete(:required)
176
- end
177
-
178
- if _type_declaration[:defaults].empty?
179
- _type_declaration.delete(:defaults)
180
- end
181
- end
182
-
183
174
  def _type_declaration
184
175
  @_type_declaration ||= begin
185
176
  sugar = {
186
177
  type: "::attributes",
187
- element_type_declarations: {},
188
- required: [],
189
- defaults: {}
178
+ element_type_declarations: {}
190
179
  }
191
180
 
192
181
  handler = Domain.current.foobara_type_builder.handler_for_class(Handlers::ExtendAttributesTypeDeclaration)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.48
4
+ version: 0.0.50
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-18 00:00:00.000000000 Z
10
+ date: 2025-01-22 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bigdecimal
@@ -219,7 +219,6 @@ files:
219
219
  - projects/domain_mapper/src/domain_mapper.rb
220
220
  - projects/domain_mapper/src/domain_mapper_lookups.rb
221
221
  - projects/entity/lib/foobara/entity.rb
222
- - projects/entity/src/concerns/attribute_helpers.rb
223
222
  - projects/entity/src/concerns/attributes.rb
224
223
  - projects/entity/src/concerns/callbacks.rb
225
224
  - projects/entity/src/concerns/initialization.rb
@@ -289,6 +288,9 @@ files:
289
288
  - projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/to_type_transformer.rb
290
289
  - projects/model/src/extensions/type_declarations/handlers/registered_type_declaration/model_class_desugarizer.rb
291
290
  - projects/model/src/model.rb
291
+ - projects/model_attribute_helpers/lib/foobara/model_attribute_helpers.rb
292
+ - projects/model_attribute_helpers/src/attribute_helper_aliases.rb
293
+ - projects/model_attribute_helpers/src/attribute_helpers.rb
292
294
  - projects/monorepo/lib/foobara/monorepo.rb
293
295
  - projects/monorepo/lib/foobara/monorepo/project.rb
294
296
  - projects/namespace/lib/foobara/namespace.rb
@@ -415,6 +417,7 @@ require_paths:
415
417
  - "./projects/in_memory_crud_driver_minimal/lib"
416
418
  - "./projects/manifest/lib"
417
419
  - "./projects/model/lib"
420
+ - "./projects/model_attribute_helpers/lib"
418
421
  - "./projects/monorepo/lib"
419
422
  - "./projects/namespace/lib"
420
423
  - "./projects/persistence/lib"
@@ -1,133 +0,0 @@
1
- module Foobara
2
- class Entity < DetachedEntity
3
- module Concerns
4
- module AttributeHelpers
5
- include Foobara::Concern
6
-
7
- module ClassMethods
8
- def attributes_for_update
9
- attributes_for_aggregate_update
10
- end
11
-
12
- # TODO: we should have metadata on the entity about whether it required a primary key
13
- # upon creation or not instead of an option here.
14
- def attributes_for_create(includes_primary_key: false)
15
- return attributes_type if includes_primary_key
16
-
17
- declaration = attributes_type.declaration_data
18
- # TODO: just slice out the element type declarations
19
- declaration = Util.deep_dup(declaration)
20
-
21
- if declaration.key?(:required) && declaration[:required].include?(primary_key_attribute)
22
- declaration[:required].delete(primary_key_attribute)
23
- end
24
-
25
- if declaration.key?(:defaults) && declaration[:defaults].include?(primary_key_attribute)
26
- declaration[:defaults].delete(primary_key_attribute)
27
- end
28
-
29
- if declaration.key?(:element_type_declarations)
30
- if declaration[:element_type_declarations].key?(primary_key_attribute)
31
- declaration[:element_type_declarations].delete(primary_key_attribute)
32
- end
33
- end
34
-
35
- handler = Domain.global.foobara_type_builder.handler_for_class(
36
- TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
37
- )
38
-
39
- handler.desugarize(declaration)
40
- end
41
-
42
- def attributes_for_aggregate_update(initial = true)
43
- declaration = attributes_type.declaration_data
44
- # TODO: just slice out the element type declarations
45
- declaration = Util.deep_dup(declaration)
46
-
47
- declaration.delete(:defaults)
48
- declaration.delete(:required)
49
-
50
- if initial
51
- declaration[:required] = [primary_key_attribute]
52
- end
53
-
54
- associations.each_pair do |data_path, type|
55
- if type.extends?(BuiltinTypes[:entity])
56
- target_class = type.target_class
57
-
58
- entry = type_declaration_value_at(declaration, DataPath.new(data_path).path)
59
- entry.clear
60
- entry.merge!(target_class.attributes_for_aggregate_update(false))
61
- end
62
- end
63
-
64
- declaration
65
- end
66
-
67
- def attributes_for_atom_update
68
- declaration = attributes_type.declaration_data
69
- # TODO: just slice out the element type declarations
70
- declaration = Util.deep_dup(declaration)
71
-
72
- declaration.delete(:defaults)
73
- declaration[:required] = [primary_key_attribute]
74
-
75
- # expect all associations to be expressed as primary key values
76
- # TODO: should we have a special type for encapsulating primary keys types??
77
- associations.each_pair do |data_path, type|
78
- if type.extends?(BuiltinTypes[:entity])
79
- target_class = type.target_class
80
- # TODO: do we really need declaration_data? Why cant we use the type directly?
81
- # TODO: make this work with the type directly for performance reasons.
82
- primary_key_type_declaration = target_class.primary_key_type.declaration_data
83
- entry = type_declaration_value_at(declaration, DataPath.new(data_path).path)
84
- entry.clear
85
- entry.merge!(primary_key_type_declaration)
86
- end
87
- end
88
-
89
- declaration
90
- end
91
-
92
- def attributes_for_find_by
93
- element_type_declarations = {}
94
-
95
- attributes_type.element_types.each_pair do |attribute_name, attribute_type|
96
- element_type_declarations[attribute_name] = attribute_type.reference_or_declaration_data
97
- end
98
-
99
- handler = Domain.global.foobara_type_builder.handler_for_class(
100
- TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
101
- )
102
-
103
- handler.desugarize(
104
- type: "::attributes",
105
- element_type_declarations:
106
- )
107
- end
108
-
109
- private
110
-
111
- def type_declaration_value_at(declaration, path_parts)
112
- return declaration if path_parts.empty?
113
-
114
- path_part, *path_parts = path_parts
115
-
116
- declaration = case path_part
117
- when :"#"
118
- declaration[:element_type_declaration]
119
- when Symbol, Integer
120
- declaration[:element_type_declarations][path_part]
121
- else
122
- # :nocov:
123
- raise "Bad path part #{path_part}"
124
- # :nocov:
125
- end
126
-
127
- type_declaration_value_at(declaration, path_parts)
128
- end
129
- end
130
- end
131
- end
132
- end
133
- end