standard_procedure_has_attributes 0.1.0 → 0.2.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 +4 -4
- data/README.md +7 -1
- data/checksums/standard_procedure_has_attributes-0.2.0.gem.sha512 +1 -0
- data/lib/has_attributes/version.rb +1 -1
- data/lib/has_attributes.rb +30 -3
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95b72e89130c7a9ae47a13d0494fc1db6e226270afd199d485784b00a0d8c1d9
|
4
|
+
data.tar.gz: 74bb291b713e6411ec4beafc93037b3c820f5a43679a2ed14dbf002cbf241e1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 454619f884749f7b3574ab27849b7a05af02fb2771fd7da1b23659929ac74387e3e1e4ca3a86d758036e2e46c0fa7d8b25b550d6cc1140a9ff558a923d8f8c04
|
7
|
+
data.tar.gz: 7c637ddb9731fd644075fcee07f62130037cf51bd70b64fce1cf53ceb45402a776ee10687b2579d9595ef07803d3eccf9a77c739f35ec50aefcf00ae78d0be81
|
data/README.md
CHANGED
@@ -71,10 +71,16 @@ Apart from storage, the attribute behaves just like any other attribute on your
|
|
71
71
|
|
72
72
|
### Defining models
|
73
73
|
|
74
|
-
You can also store references to other models using the `has_model` declaration. This stores a [GlobalID](https://github.com/rails/globalid) inside the data field, converting the reference back to a real model when needed.
|
74
|
+
You can also store references to other models using the `has_model` declaration. This stores a [GlobalID](https://github.com/rails/globalid) inside the data field, converting the reference back to a real model when needed. `has_model` reloads the model on-demand so there is no database request until you actually try to access the stored model. However, because of the way this works, you cannot eager-load stored models, so be careful when trying to display large numbers of records, as you will end up with N+1 queries.
|
75
75
|
|
76
76
|
When using `has_model` you can optionally specify a class name (as a string). If given, the model will be tested to make sure it is that class (or a subclass of it) and, if not the record is marked as invalid.
|
77
77
|
|
78
|
+
### Defining arrays of models
|
79
|
+
|
80
|
+
Similarly, you can store arrays of models using the `has_models` declaration. Internally this stores a comma separated list of GlobalIDs inside the data field, using `GlobalID::Locator.locate_many` to convert the array back to models as efficiently as possible. Again, eager loading is not possible so watch out for N+1 queries.
|
81
|
+
|
82
|
+
Like `has_model` you can optionally specify a class name (as a string), which then validates the provided models to make sure they are valid classes or subclasses.
|
83
|
+
|
78
84
|
## Development
|
79
85
|
|
80
86
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1 @@
|
|
1
|
+
a81ee1c0a59142295d6bbfddefd39697884c3de3b911836c49d8f51ffa75b73c21ffe2efa1a7ac90235b640ce5aa07d378d09f4f4b76371a416885704d1a184a
|
data/lib/has_attributes.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative "has_attributes/version"
|
4
4
|
require "active_support/concern"
|
5
5
|
require "active_support/core_ext/string/inflections"
|
6
|
-
require "
|
6
|
+
require "global_id"
|
7
7
|
|
8
8
|
module HasAttributes
|
9
9
|
extend ActiveSupport::Concern
|
@@ -12,7 +12,7 @@ module HasAttributes
|
|
12
12
|
class_methods do
|
13
13
|
def has_attribute name, cast_type = :string, field_name: :data, **options
|
14
14
|
field_name = field_name.to_sym
|
15
|
-
name = name.
|
15
|
+
name = name.to_s
|
16
16
|
typecaster = cast_type.nil? ? nil : ActiveRecord::Type.lookup(cast_type)
|
17
17
|
typecast_value = ->(value) { typecaster.nil? ? value : typecaster.cast(value) }
|
18
18
|
define_attribute_method name
|
@@ -38,7 +38,7 @@ module HasAttributes
|
|
38
38
|
validate :"#{name}_class_name", if: -> { send(name).present? } if class_name.present?
|
39
39
|
|
40
40
|
define_method(name.to_sym) do
|
41
|
-
model_id = send id_attribute
|
41
|
+
model_id = send id_attribute.to_sym
|
42
42
|
model_id.nil? ? nil : GlobalID::Locator.locate(model_id.sub("modelid-", ""))
|
43
43
|
rescue ActiveRecord::RecordNotFound
|
44
44
|
nil
|
@@ -53,5 +53,32 @@ module HasAttributes
|
|
53
53
|
errors.add name, :invalid unless send(name).is_a?(class_name.constantize)
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
def has_models name, class_name = nil, field_name: :data, **options
|
58
|
+
name = name.to_sym
|
59
|
+
array_attribute = "#{name}_array"
|
60
|
+
has_attribute array_attribute, field_name:, **options
|
61
|
+
validate :"#{name}_class_names", if: -> { send(name).any? } if class_name.present?
|
62
|
+
|
63
|
+
define_method(name.to_sym) do
|
64
|
+
model_ids = send(array_attribute).to_s.split(",").map do |model_id|
|
65
|
+
model_id.to_s.sub("modelid-", "")
|
66
|
+
end
|
67
|
+
GlobalID::Locator.locate_many(model_ids)
|
68
|
+
rescue ActiveRecord::RecordNotFound
|
69
|
+
[]
|
70
|
+
end
|
71
|
+
|
72
|
+
define_method(:"#{name}=") do |models|
|
73
|
+
model_ids = Array.wrap(models).map do |model|
|
74
|
+
model.nil? ? nil : "modelid-#{model.to_global_id}"
|
75
|
+
end.compact
|
76
|
+
send :"#{array_attribute}=", model_ids.join(",")
|
77
|
+
end
|
78
|
+
|
79
|
+
define_method :"#{name}_class_names" do
|
80
|
+
errors.add name, :invalid if send(name).any? { |model| !model.is_a?(class_name.constantize) }
|
81
|
+
end
|
82
|
+
end
|
56
83
|
end
|
57
84
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: standard_procedure_has_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahoul Baruah
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-07-01 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activesupport
|
@@ -23,6 +23,20 @@ dependencies:
|
|
23
23
|
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
25
|
version: '7.1'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: globalid
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.2'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.2'
|
26
40
|
description: Store Rails attributes in a serialized JSON field, with support for GlobalIDs
|
27
41
|
and indexes
|
28
42
|
email:
|
@@ -38,6 +52,7 @@ files:
|
|
38
52
|
- README.md
|
39
53
|
- Rakefile
|
40
54
|
- checksums/standard_procedure_has_attributes-0.1.0.gem.sha512
|
55
|
+
- checksums/standard_procedure_has_attributes-0.2.0.gem.sha512
|
41
56
|
- lib/has_attributes.rb
|
42
57
|
- lib/has_attributes/version.rb
|
43
58
|
- sig/has_attributes.rbs
|