support_table_data 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +51 -1
- data/VERSION +1 -1
- data/lib/support_table_data.rb +63 -33
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edd9a57acfcdadac9ce60c8520b4fa2d3cccda8bebc2bfe1eeea54981bcf5488
|
4
|
+
data.tar.gz: 31f38443c7edd8af91d3f4de125dbb4a32b8b38612c84ce321633971063fd29b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d425621345850d9bd2ec8f878eefcbeb667fb6981d2d74b3b2174e3943463bf95470727f3925f83ba966766fe6817ab8e11b5ba9ed30ff9a6c1bb0826229c261
|
7
|
+
data.tar.gz: 152ccc8196e8eb7fd68e5e94cc6dcea5307e98d3e1ef23a1ed9e5e320d0d511beac19494c0242eb1a858ceebc9eba27b29e68023c69476ea5046273e6f9b1445
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## 1.2.0
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Added `named_instance` method to load a named instance from the database.
|
12
|
+
- Added class method `named_instance_data` to return attributes from the data files for a named instance.
|
13
|
+
- Added handling for `has_many through` associations to load the dependent through associations first.
|
14
|
+
|
7
15
|
## 1.1.2
|
8
16
|
|
9
17
|
### Fixed
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# Support Table Data
|
2
2
|
|
3
3
|
[![Continuous Integration](https://github.com/bdurand/support_table_data/actions/workflows/continuous_integration.yml/badge.svg)](https://github.com/bdurand/support_table_data/actions/workflows/continuous_integration.yml)
|
4
|
-
[![Regression Test](https://github.com/bdurand/support_table_data/actions/workflows/regression_test.yml/badge.svg)](https://github.com/bdurand/support_table_data/actions/workflows/regression_test.yml)
|
5
4
|
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
|
6
5
|
[![Gem Version](https://badge.fury.io/rb/support_table_data.svg)](https://badge.fury.io/rb/support_table_data)
|
7
6
|
|
@@ -121,6 +120,55 @@ Status.in_progress_id # => 2
|
|
121
120
|
Status.completed_id # => 3
|
122
121
|
```
|
123
122
|
|
123
|
+
You can also use named instances to maintain associations between you models. In order to do this you'll need to implement a custom setter method.
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
class Group < ApplicationRecord
|
127
|
+
include SupportTableData
|
128
|
+
|
129
|
+
has_many :statuses
|
130
|
+
end
|
131
|
+
|
132
|
+
class Status < ApplicationRecord
|
133
|
+
include SupportTableData
|
134
|
+
|
135
|
+
belongs_to :group
|
136
|
+
|
137
|
+
def group_name=(instance_name)
|
138
|
+
self.group = Group.named_instance(instance_name)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
This then allows you to reference groups by instance name in the statuses.yml file:
|
144
|
+
|
145
|
+
```yaml
|
146
|
+
# groups.yml
|
147
|
+
not_done:
|
148
|
+
id: 1
|
149
|
+
name: Not Done
|
150
|
+
|
151
|
+
done:
|
152
|
+
id: 2
|
153
|
+
name: Done
|
154
|
+
|
155
|
+
# statuses.yml
|
156
|
+
pending:
|
157
|
+
id: 1
|
158
|
+
name: Pending
|
159
|
+
group_name: not_done
|
160
|
+
|
161
|
+
in_progress:
|
162
|
+
id: 2
|
163
|
+
name: In Progress
|
164
|
+
group_name: not_done
|
165
|
+
|
166
|
+
completed:
|
167
|
+
id: 3
|
168
|
+
name: Completed
|
169
|
+
group_name: done
|
170
|
+
```
|
171
|
+
|
124
172
|
### Caching
|
125
173
|
|
126
174
|
You can use the companion [support_table_cache gem](https://github.com/bdurand/support_table_cache) to add caching support to your models. That way your application won't need to constantly query the database for records that will never change.
|
@@ -164,6 +212,8 @@ Loading data is done inside a database transaction. No changes will be persisted
|
|
164
212
|
|
165
213
|
You can synchronize the data in all models by calling `SupportTableData.sync_all!`. This method will discover all ActiveRecord models that include `SupportTableData` and synchronize each of them. (Note that there can be issues discovering all support table models in a Rails application if eager loading is turned off.) The discovery mechanism will try to detect unloaded classes by looking at the file names in the support table data directory so it's best to stick to standard Rails naming conventions for your data files.
|
166
214
|
|
215
|
+
The load order for models will resolve any dependencies between models. So if one model has a `belongs_to` association with another model, then the belongs to model will be loaded first.
|
216
|
+
|
167
217
|
You need to call `SupportTableData.sync_all!` when deploying your application. This gem includes a rake task `support_table_data:sync` that is suitable for hooking into deploy scripts. An easy way to hook it into a Rails application is by enhancing the `db:migrate` task so that the sync task runs immediately after database migrations are run. You can do this by adding code to a Rakefile in your application's `lib/tasks` directory:
|
168
218
|
|
169
219
|
```ruby
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/lib/support_table_data.rb
CHANGED
@@ -8,7 +8,24 @@
|
|
8
8
|
module SupportTableData
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
|
-
|
11
|
+
included do
|
12
|
+
# Internal variables used for memoization.
|
13
|
+
@support_table_data_files = []
|
14
|
+
@support_table_attribute_helpers = {}
|
15
|
+
@support_table_instance_names = {}
|
16
|
+
@support_table_instance_keys = nil
|
17
|
+
|
18
|
+
# Define the attribute used as the key of the hash in the data files.
|
19
|
+
# This should be a value that never changes. By default the key attribute will be the id.
|
20
|
+
class_attribute :support_table_key_attribute, instance_accessor: false
|
21
|
+
|
22
|
+
# Define the directory where data files should be loaded from. This value will override the global
|
23
|
+
# value set by SupportTableData.data_directory. This is only used if relative paths are passed
|
24
|
+
# in to add_support_table_data.
|
25
|
+
class_attribute :support_table_data_directory, instance_accessor: false
|
26
|
+
end
|
27
|
+
|
28
|
+
class_methods do
|
12
29
|
# Synchronize the rows in the table with the values defined in the data files added with
|
13
30
|
# `add_support_table_data`. Note that rows will not be deleted if they are no longer in
|
14
31
|
# the data files.
|
@@ -58,7 +75,6 @@ module SupportTableData
|
|
58
75
|
# this model or the global directory set with SupportTableData.data_directory.
|
59
76
|
# @return [void]
|
60
77
|
def add_support_table_data(data_file_path)
|
61
|
-
@support_table_data_files ||= []
|
62
78
|
root_dir = (support_table_data_directory || SupportTableData.data_directory || Dir.pwd)
|
63
79
|
@support_table_data_files << File.expand_path(data_file_path, root_dir)
|
64
80
|
define_support_table_named_instances
|
@@ -72,7 +88,6 @@ module SupportTableData
|
|
72
88
|
# @param attributes [String, Symbol] The names of the attributes to add helper methods for.
|
73
89
|
# @return [void]
|
74
90
|
def named_instance_attribute_helpers(*attributes)
|
75
|
-
@support_table_attribute_helpers ||= {}
|
76
91
|
attributes.flatten.collect(&:to_s).each do |attribute|
|
77
92
|
@support_table_attribute_helpers[attribute] = []
|
78
93
|
end
|
@@ -84,7 +99,6 @@ module SupportTableData
|
|
84
99
|
#
|
85
100
|
# @return [Array<String>] List of attribute names.
|
86
101
|
def support_table_attribute_helpers
|
87
|
-
@support_table_attribute_helpers ||= {}
|
88
102
|
@support_table_attribute_helpers.keys
|
89
103
|
end
|
90
104
|
|
@@ -92,7 +106,6 @@ module SupportTableData
|
|
92
106
|
#
|
93
107
|
# @return [Array<Hash>] List of attributes for all records in the data files.
|
94
108
|
def support_table_data
|
95
|
-
@support_table_data_files ||= []
|
96
109
|
data = {}
|
97
110
|
key_attribute = (support_table_key_attribute || primary_key).to_s
|
98
111
|
|
@@ -114,19 +127,51 @@ module SupportTableData
|
|
114
127
|
data.values
|
115
128
|
end
|
116
129
|
|
130
|
+
# Get the data for a named instances from the data files.
|
131
|
+
#
|
132
|
+
# @return [Hasn] Hash of named instance attributes.
|
133
|
+
def named_instance_data(name)
|
134
|
+
data = {}
|
135
|
+
name = name.to_s
|
136
|
+
|
137
|
+
@support_table_data_files.each do |data_file_path|
|
138
|
+
file_data = support_table_parse_data_file(data_file_path)
|
139
|
+
next unless file_data.is_a?(Hash)
|
140
|
+
|
141
|
+
file_data.each do |instance_name, attributes|
|
142
|
+
next unless name == instance_name.to_s
|
143
|
+
next unless attributes.is_a?(Hash)
|
144
|
+
|
145
|
+
data.merge!(attributes)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
data
|
150
|
+
end
|
151
|
+
|
117
152
|
# Get the names of all named instances.
|
118
153
|
#
|
119
154
|
# @return [Array<String>] List of all instance names.
|
120
155
|
def instance_names
|
121
|
-
@support_table_instance_names
|
122
|
-
|
156
|
+
@support_table_instance_names.keys
|
157
|
+
end
|
158
|
+
|
159
|
+
# Load a named instance from the database.
|
160
|
+
#
|
161
|
+
# @param instance_name [String, Symbol] The name of the instance to load as defined in the data files.
|
162
|
+
# @return [ActiveRecord::Base] The instance loaded from the database.
|
163
|
+
# @raise [ActiveRecord::RecordNotFound] If the instance does not exist.
|
164
|
+
def named_instance(instance_name)
|
165
|
+
key_attribute = (support_table_key_attribute || primary_key).to_s
|
166
|
+
instance_name = instance_name.to_s
|
167
|
+
find_by!(key_attribute => @support_table_instance_names[instance_name])
|
123
168
|
end
|
124
169
|
|
125
170
|
# Get the key values for all instances loaded from the data files.
|
126
171
|
#
|
127
172
|
# @return [Array] List of all the key attribute values.
|
128
173
|
def instance_keys
|
129
|
-
|
174
|
+
if @support_table_instance_keys.nil?
|
130
175
|
key_attribute = (support_table_key_attribute || primary_key).to_s
|
131
176
|
values = []
|
132
177
|
support_table_data.each do |attributes|
|
@@ -157,9 +202,6 @@ module SupportTableData
|
|
157
202
|
private
|
158
203
|
|
159
204
|
def define_support_table_named_instances
|
160
|
-
@support_table_data_files ||= []
|
161
|
-
@support_table_instance_names ||= Set.new
|
162
|
-
|
163
205
|
@support_table_data_files.each do |file_path|
|
164
206
|
data = support_table_parse_data_file(file_path)
|
165
207
|
next unless data.is_a?(Hash)
|
@@ -188,7 +230,7 @@ module SupportTableData
|
|
188
230
|
unless @support_table_instance_names.include?(method_name)
|
189
231
|
define_support_table_instance_helper(method_name, key_attribute, key_value)
|
190
232
|
define_support_table_predicates_helper("#{method_name}?", key_attribute, key_value)
|
191
|
-
@support_table_instance_names
|
233
|
+
@support_table_instance_names[method_name] = key_value
|
192
234
|
end
|
193
235
|
|
194
236
|
if defined?(@support_table_attribute_helpers)
|
@@ -203,8 +245,6 @@ module SupportTableData
|
|
203
245
|
end
|
204
246
|
|
205
247
|
def define_support_table_instance_helper(method_name, attribute_name, attribute_value)
|
206
|
-
return if @support_table_instance_names.include?("self.#{method_name}")
|
207
|
-
|
208
248
|
if respond_to?(method_name, true)
|
209
249
|
raise ArgumentError.new("Could not define support table helper method #{name}.#{method_name} because it is already a defined method")
|
210
250
|
end
|
@@ -217,8 +257,6 @@ module SupportTableData
|
|
217
257
|
end
|
218
258
|
|
219
259
|
def define_support_table_instance_attribute_helper(method_name, attribute_value)
|
220
|
-
return if @support_table_instance_names.include?("self.#{method_name}")
|
221
|
-
|
222
260
|
if respond_to?(method_name, true)
|
223
261
|
raise ArgumentError.new("Could not define support table helper method #{name}.#{method_name} because it is already a defined method")
|
224
262
|
end
|
@@ -231,8 +269,6 @@ module SupportTableData
|
|
231
269
|
end
|
232
270
|
|
233
271
|
def define_support_table_predicates_helper(method_name, attribute_name, attribute_value)
|
234
|
-
return if @support_table_instance_names.include?(method_name)
|
235
|
-
|
236
272
|
if method_defined?(method_name) || private_method_defined?(method_name)
|
237
273
|
raise ArgumentError.new("Could not define support table helper method #{name}##{method_name} because it is already a defined method")
|
238
274
|
end
|
@@ -268,17 +304,6 @@ module SupportTableData
|
|
268
304
|
end
|
269
305
|
end
|
270
306
|
|
271
|
-
included do
|
272
|
-
# Define the attribute used as the key of the hash in the data files.
|
273
|
-
# This should be a value that never changes. By default the key attribute will be the id.
|
274
|
-
class_attribute :support_table_key_attribute, instance_accessor: false
|
275
|
-
|
276
|
-
# Define the directory where data files should be loaded from. This value will override the global
|
277
|
-
# value set by SupportTableData.data_directory. This is only used if relative paths are passed
|
278
|
-
# in to add_support_table_data.
|
279
|
-
class_attribute :support_table_data_directory, instance_accessor: false
|
280
|
-
end
|
281
|
-
|
282
307
|
class << self
|
283
308
|
# Specify the default directory for data files.
|
284
309
|
attr_writer :data_directory
|
@@ -373,11 +398,16 @@ module SupportTableData
|
|
373
398
|
# @return [Array<Class>]
|
374
399
|
def support_table_dependencies(klass)
|
375
400
|
dependencies = []
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
401
|
+
|
402
|
+
klass.reflections.values.each do |reflection|
|
403
|
+
next if reflection.polymorphic?
|
404
|
+
next unless reflection.klass.include?(SupportTableData)
|
405
|
+
next if reflection.klass <= klass
|
406
|
+
next unless reflection.belongs_to? || reflection.through_reflection?
|
407
|
+
|
408
|
+
dependencies << reflection.klass
|
380
409
|
end
|
410
|
+
|
381
411
|
dependencies
|
382
412
|
end
|
383
413
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: support_table_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Durand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -72,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: '0'
|
74
74
|
requirements: []
|
75
|
-
rubygems_version: 3.4.
|
75
|
+
rubygems_version: 3.4.12
|
76
76
|
signing_key:
|
77
77
|
specification_version: 4
|
78
78
|
summary: Extension for ActiveRecord models to manage synchronizing data in support/lookup
|