support_table_data 1.5.0 → 1.5.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +3 -1
- data/VERSION +1 -1
- data/lib/support_table_data/documentation/source_file.rb +3 -0
- data/lib/tasks/support_table_data.rake +17 -11
- data/lib/tasks/utils.rb +15 -7
- data/support_table_data.gemspec +1 -0
- data/test_app/app/models/status.rb +109 -0
- metadata +1 -2
- data/AGENTS.md +0 -140
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '081b2612659ea90591ecf5fd7386acbb9d10dbd90c20301e12fba39d3d81e4b3'
|
|
4
|
+
data.tar.gz: b7d4960153f4799031127c8e2fb6ffaa5da49acc1e59833b64c9f417dd9d77df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e38a2f56f37888a737c8493ec0078666cf8a138415326946829c506a57fc81f5bc3e8407232e7bacbd82a5d0066d9513dd14340360e9d4179a3b1d51a7d69517
|
|
7
|
+
data.tar.gz: 569bbabe38749923686c5d9aa757851f6ba3fad64317f18e3fdb209aec9c714ed1f020a6c07a1588464d1ed9c129bb983ae25d5378ae324b0abee8e467e0fa96
|
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.5.1
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- YARD documentation tasks can now take an optional file path argument to add, verify, or remove documentation for a specific support table model instead of all models. For example, you can run `bundle exec rake support_table_data:yard_docs:add[app/models/color.rb]` to add documentation for the `Color` model.
|
|
12
|
+
- Added comment in generated YARD documentation indicating the command to run to update them so that it's clear to users how to keep the documentation up to date.
|
|
13
|
+
- Aliased `support_table_data:yard_docs` to `support_table_data:yard_docs:add` for convenience since adding the documentation is the most common action.
|
|
14
|
+
|
|
7
15
|
## 1.5.0
|
|
8
16
|
|
|
9
17
|
### Added
|
data/README.md
CHANGED
|
@@ -187,7 +187,9 @@ completed:
|
|
|
187
187
|
|
|
188
188
|
#### Documenting Named Instance Helpers
|
|
189
189
|
|
|
190
|
-
In a Rails application, you can add YARD documentation for the named instance helpers by running the rake task `support_table_data:yard_docs
|
|
190
|
+
In a Rails application, you can add YARD documentation for the named instance helpers by running the rake task `support_table_data:yard_docs`. This will add YARD comments to your model classes for each of the named instance helper methods defined on the model. Adding this documentation will help IDEs provide better code completion and inline documentation for the helper methods and expose the methods to AI agents.
|
|
191
|
+
|
|
192
|
+
To update a single model file, pass an optional file path argument, for example: `bundle exec rake "support_table_data:yard_docs[app/models/status.rb]"`.
|
|
191
193
|
|
|
192
194
|
The default behavior is to add the documentation comments at the end of the model class by reopening the class definition. If you prefer to have the documentation comments appear elsewhere in the file, you can add the following markers to your model class and the YARD documentation will be inserted between these markers.
|
|
193
195
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.5.
|
|
1
|
+
1.5.1
|
|
@@ -9,6 +9,7 @@ module SupportTableData
|
|
|
9
9
|
END_YARD_COMMENT = "# End YARD docs for support_table_data"
|
|
10
10
|
YARD_COMMENT_REGEX = /^(?<indent>[ \t]*)#{BEGIN_YARD_COMMENT}.*^[ \t]*#{END_YARD_COMMENT}$/m
|
|
11
11
|
CLASS_DEF_REGEX = /^[ \t]*class [a-zA-Z_0-9:]+.*?$/
|
|
12
|
+
UPDATE_COMMAND_COMMENT = "# To update these docs, run `bundle exec rake support_table_data:yard_docs`"
|
|
12
13
|
|
|
13
14
|
# Initialize a new source file representation.
|
|
14
15
|
#
|
|
@@ -53,6 +54,7 @@ module SupportTableData
|
|
|
53
54
|
|
|
54
55
|
updated_source = source[0, existing_yard_docs.begin(0)]
|
|
55
56
|
updated_source << "#{indent}#{BEGIN_YARD_COMMENT}\n"
|
|
57
|
+
updated_source << "#{indent}#{UPDATE_COMMAND_COMMENT}\n"
|
|
56
58
|
updated_source << "#{indent}class #{klass.name}\n" if has_class_def
|
|
57
59
|
updated_source << yard_docs
|
|
58
60
|
updated_source << "\n#{indent}end" if has_class_def
|
|
@@ -62,6 +64,7 @@ module SupportTableData
|
|
|
62
64
|
else
|
|
63
65
|
yard_comments = <<~SOURCE.chomp("\n")
|
|
64
66
|
#{BEGIN_YARD_COMMENT}
|
|
67
|
+
#{UPDATE_COMMAND_COMMENT}
|
|
65
68
|
class #{klass.name}
|
|
66
69
|
#{yard_docs.lines.map { |line| line.blank? ? "\n" : " #{line}" }.join}
|
|
67
70
|
end
|
|
@@ -23,14 +23,16 @@ namespace :support_table_data do
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
task yard_docs: "yard_docs:add"
|
|
27
|
+
|
|
26
28
|
namespace :yard_docs do
|
|
27
|
-
desc "Adds YARD documentation comments to models to document the named instance methods."
|
|
28
|
-
task add: :environment do
|
|
29
|
+
desc "Adds YARD documentation comments to models to document the named instance methods. Optional arg: file_path"
|
|
30
|
+
task :add, [:file_path] => :environment do |_task, args|
|
|
29
31
|
require_relative "../support_table_data/documentation"
|
|
30
32
|
require_relative "utils"
|
|
31
33
|
|
|
32
34
|
SupportTableData::Tasks::Utils.eager_load!
|
|
33
|
-
SupportTableData::Tasks::Utils.support_table_sources.each do |source_file|
|
|
35
|
+
SupportTableData::Tasks::Utils.support_table_sources(args[:file_path]).each do |source_file|
|
|
34
36
|
next if source_file.yard_docs_up_to_date?
|
|
35
37
|
|
|
36
38
|
source_file.path.write(source_file.source_with_yard_docs)
|
|
@@ -38,13 +40,13 @@ namespace :support_table_data do
|
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
42
|
|
|
41
|
-
desc "Removes YARD documentation comments added by support_table_data from models."
|
|
42
|
-
task remove: :environment do
|
|
43
|
+
desc "Removes YARD documentation comments added by support_table_data from models. Optional arg: file_path"
|
|
44
|
+
task :remove, [:file_path] => :environment do |_task, args|
|
|
43
45
|
require_relative "../support_table_data/documentation"
|
|
44
46
|
require_relative "utils"
|
|
45
47
|
|
|
46
48
|
SupportTableData::Tasks::Utils.eager_load!
|
|
47
|
-
SupportTableData::Tasks::Utils.support_table_sources.each do |source_file|
|
|
49
|
+
SupportTableData::Tasks::Utils.support_table_sources(args[:file_path]).each do |source_file|
|
|
48
50
|
next unless source_file.has_yard_docs?
|
|
49
51
|
|
|
50
52
|
source_file.path.write(source_file.source_without_yard_docs)
|
|
@@ -52,15 +54,15 @@ namespace :support_table_data do
|
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
desc "Verify that
|
|
56
|
-
task verify: :environment do
|
|
57
|
+
desc "Verify that support table models have up to date YARD docs for named instance methods. Optional arg: file_path"
|
|
58
|
+
task :verify, [:file_path] => :environment do |_task, args|
|
|
57
59
|
require_relative "../support_table_data/documentation"
|
|
58
60
|
require_relative "utils"
|
|
59
61
|
|
|
60
62
|
SupportTableData::Tasks::Utils.eager_load!
|
|
61
63
|
|
|
62
64
|
all_up_to_date = true
|
|
63
|
-
SupportTableData::Tasks::Utils.support_table_sources.each do |source_file|
|
|
65
|
+
SupportTableData::Tasks::Utils.support_table_sources(args[:file_path]).each do |source_file|
|
|
64
66
|
unless source_file.yard_docs_up_to_date?
|
|
65
67
|
puts "YARD documentation is not up to date for #{source_file.klass.name}."
|
|
66
68
|
all_up_to_date = false
|
|
@@ -68,9 +70,13 @@ namespace :support_table_data do
|
|
|
68
70
|
end
|
|
69
71
|
|
|
70
72
|
if all_up_to_date
|
|
71
|
-
|
|
73
|
+
if args[:file_path]
|
|
74
|
+
puts "YARD documentation is up to date for #{args[:file_path]}."
|
|
75
|
+
else
|
|
76
|
+
puts "All support table models have up to date YARD documentation."
|
|
77
|
+
end
|
|
72
78
|
else
|
|
73
|
-
raise "Run bundle exec
|
|
79
|
+
raise "Run bundle exec rake support_table_data:yard_docs to update the documentation."
|
|
74
80
|
end
|
|
75
81
|
end
|
|
76
82
|
end
|
data/lib/tasks/utils.rb
CHANGED
|
@@ -18,14 +18,17 @@ module SupportTableData
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
# Return
|
|
21
|
+
# Return all source files for models that include SupportTableData.
|
|
22
22
|
#
|
|
23
|
+
# @param file_path [String, Pathname, nil] Optional file path to filter by.
|
|
23
24
|
# @return [Array<SupportTableData::Documentation::SourceFile>]
|
|
24
|
-
def support_table_sources
|
|
25
|
+
def support_table_sources(file_path = nil)
|
|
26
|
+
require_relative file_path if file_path
|
|
27
|
+
|
|
25
28
|
sources = []
|
|
26
29
|
|
|
27
30
|
ActiveRecord::Base.descendants.each do |klass|
|
|
28
|
-
next unless klass.
|
|
31
|
+
next unless klass.include?(SupportTableData)
|
|
29
32
|
|
|
30
33
|
begin
|
|
31
34
|
next if klass.instance_names.empty?
|
|
@@ -34,13 +37,18 @@ module SupportTableData
|
|
|
34
37
|
next
|
|
35
38
|
end
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
next unless
|
|
40
|
+
model_file_path = SupportTableData::Tasks::Utils.model_file_path(klass)
|
|
41
|
+
next unless model_file_path&.file? && model_file_path.readable?
|
|
39
42
|
|
|
40
|
-
sources << Documentation::SourceFile.new(klass,
|
|
43
|
+
sources << Documentation::SourceFile.new(klass, model_file_path)
|
|
41
44
|
end
|
|
42
45
|
|
|
43
|
-
sources
|
|
46
|
+
return sources if file_path.nil?
|
|
47
|
+
|
|
48
|
+
resolved_path = Pathname.new(file_path.to_s).expand_path
|
|
49
|
+
sources.select { |source| source.path.expand_path == resolved_path }
|
|
50
|
+
rescue ArgumentError
|
|
51
|
+
[]
|
|
44
52
|
end
|
|
45
53
|
|
|
46
54
|
def model_file_path(klass)
|
data/support_table_data.gemspec
CHANGED
|
@@ -9,3 +9,112 @@ class Status < ApplicationRecord
|
|
|
9
9
|
|
|
10
10
|
validates :code, presence: true, uniqueness: true
|
|
11
11
|
end
|
|
12
|
+
|
|
13
|
+
# Begin YARD docs for support_table_data
|
|
14
|
+
# To update these docs, run `bundle exec rake support_table_data:yard_docs`
|
|
15
|
+
class Status
|
|
16
|
+
# @!group Named Instances
|
|
17
|
+
|
|
18
|
+
# Find the named instance +active+ from the database.
|
|
19
|
+
#
|
|
20
|
+
# @!method self.active
|
|
21
|
+
# @return [Status]
|
|
22
|
+
# @raise [ActiveRecord::RecordNotFound] if the record does not exist
|
|
23
|
+
# @!visibility public
|
|
24
|
+
|
|
25
|
+
# Check if this record is the named instance +active+.
|
|
26
|
+
#
|
|
27
|
+
# @!method active?
|
|
28
|
+
# @return [Boolean]
|
|
29
|
+
# @!visibility public
|
|
30
|
+
|
|
31
|
+
# Get the name attribute from the data file
|
|
32
|
+
# for the named instance +active+.
|
|
33
|
+
#
|
|
34
|
+
# @!method self.active_name
|
|
35
|
+
# @return [Object]
|
|
36
|
+
# @!visibility public
|
|
37
|
+
|
|
38
|
+
# Find the named instance +canceled+ from the database.
|
|
39
|
+
#
|
|
40
|
+
# @!method self.canceled
|
|
41
|
+
# @return [Status]
|
|
42
|
+
# @raise [ActiveRecord::RecordNotFound] if the record does not exist
|
|
43
|
+
# @!visibility public
|
|
44
|
+
|
|
45
|
+
# Check if this record is the named instance +canceled+.
|
|
46
|
+
#
|
|
47
|
+
# @!method canceled?
|
|
48
|
+
# @return [Boolean]
|
|
49
|
+
# @!visibility public
|
|
50
|
+
|
|
51
|
+
# Get the name attribute from the data file
|
|
52
|
+
# for the named instance +canceled+.
|
|
53
|
+
#
|
|
54
|
+
# @!method self.canceled_name
|
|
55
|
+
# @return [Object]
|
|
56
|
+
# @!visibility public
|
|
57
|
+
|
|
58
|
+
# Find the named instance +completed+ from the database.
|
|
59
|
+
#
|
|
60
|
+
# @!method self.completed
|
|
61
|
+
# @return [Status]
|
|
62
|
+
# @raise [ActiveRecord::RecordNotFound] if the record does not exist
|
|
63
|
+
# @!visibility public
|
|
64
|
+
|
|
65
|
+
# Check if this record is the named instance +completed+.
|
|
66
|
+
#
|
|
67
|
+
# @!method completed?
|
|
68
|
+
# @return [Boolean]
|
|
69
|
+
# @!visibility public
|
|
70
|
+
|
|
71
|
+
# Get the name attribute from the data file
|
|
72
|
+
# for the named instance +completed+.
|
|
73
|
+
#
|
|
74
|
+
# @!method self.completed_name
|
|
75
|
+
# @return [Object]
|
|
76
|
+
# @!visibility public
|
|
77
|
+
|
|
78
|
+
# Find the named instance +failed+ from the database.
|
|
79
|
+
#
|
|
80
|
+
# @!method self.failed
|
|
81
|
+
# @return [Status]
|
|
82
|
+
# @raise [ActiveRecord::RecordNotFound] if the record does not exist
|
|
83
|
+
# @!visibility public
|
|
84
|
+
|
|
85
|
+
# Check if this record is the named instance +failed+.
|
|
86
|
+
#
|
|
87
|
+
# @!method failed?
|
|
88
|
+
# @return [Boolean]
|
|
89
|
+
# @!visibility public
|
|
90
|
+
|
|
91
|
+
# Get the name attribute from the data file
|
|
92
|
+
# for the named instance +failed+.
|
|
93
|
+
#
|
|
94
|
+
# @!method self.failed_name
|
|
95
|
+
# @return [Object]
|
|
96
|
+
# @!visibility public
|
|
97
|
+
|
|
98
|
+
# Find the named instance +pending+ from the database.
|
|
99
|
+
#
|
|
100
|
+
# @!method self.pending
|
|
101
|
+
# @return [Status]
|
|
102
|
+
# @raise [ActiveRecord::RecordNotFound] if the record does not exist
|
|
103
|
+
# @!visibility public
|
|
104
|
+
|
|
105
|
+
# Check if this record is the named instance +pending+.
|
|
106
|
+
#
|
|
107
|
+
# @!method pending?
|
|
108
|
+
# @return [Boolean]
|
|
109
|
+
# @!visibility public
|
|
110
|
+
|
|
111
|
+
# Get the name attribute from the data file
|
|
112
|
+
# for the named instance +pending+.
|
|
113
|
+
#
|
|
114
|
+
# @!method self.pending_name
|
|
115
|
+
# @return [Object]
|
|
116
|
+
# @!visibility public
|
|
117
|
+
|
|
118
|
+
# @!endgroup
|
|
119
|
+
end
|
|
120
|
+
# End YARD docs for support_table_data
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: support_table_data
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brian Durand
|
|
@@ -43,7 +43,6 @@ executables: []
|
|
|
43
43
|
extensions: []
|
|
44
44
|
extra_rdoc_files: []
|
|
45
45
|
files:
|
|
46
|
-
- AGENTS.md
|
|
47
46
|
- ARCHITECTURE.md
|
|
48
47
|
- CHANGELOG.md
|
|
49
48
|
- MIT-LICENSE.txt
|
data/AGENTS.md
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Copilot Instructions for support_table_data
|
|
2
|
-
|
|
3
|
-
## Project Overview
|
|
4
|
-
|
|
5
|
-
A Ruby gem providing an ActiveRecord mixin for managing support/lookup tables with canonical data defined in YAML/JSON/CSV files. The gem dynamically generates helper methods to reference specific records naturally in code (e.g., `Status.pending` instead of `Status.find_by(name: 'Pending')`).
|
|
6
|
-
|
|
7
|
-
**Core concept**: Support tables blur the line between data and code—they contain small canonical datasets that must exist for the application to work.
|
|
8
|
-
|
|
9
|
-
## Architecture
|
|
10
|
-
|
|
11
|
-
### Key Components
|
|
12
|
-
|
|
13
|
-
- **`SupportTableData` module** ([lib/support_table_data.rb](lib/support_table_data.rb)): Main concern mixed into ActiveRecord models
|
|
14
|
-
- **Named instance system**: Dynamically generates class methods (`.pending`), predicate methods (`.pending?`), and attribute helpers (`.pending_id`) from hash-based data files
|
|
15
|
-
- **Data sync engine**: Compares canonical data files with database records, creating/updating as needed in atomic transactions
|
|
16
|
-
- **File parsers**: Supports YAML, JSON, and CSV formats with unified interface
|
|
17
|
-
|
|
18
|
-
### Data Flow
|
|
19
|
-
|
|
20
|
-
1. Data files (YAML/JSON/CSV) define canonical records with unique key attributes
|
|
21
|
-
2. `add_support_table_data` registers file paths and triggers method generation for hash-based files
|
|
22
|
-
3. `sync_table_data!` parses files, loads matching DB records, and updates/creates within transactions
|
|
23
|
-
4. Named instance methods are dynamically defined via `class_eval` with memoization
|
|
24
|
-
|
|
25
|
-
## Development Workflows
|
|
26
|
-
|
|
27
|
-
### Running Tests
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
bundle exec rspec # Run all specs
|
|
31
|
-
bundle exec rspec spec/support_table_data_spec.rb # Single file
|
|
32
|
-
bundle exec rake appraisals # Test against all ActiveRecord versions
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Uses RSpec with in-memory SQLite database. Test models defined in [spec/models.rb](spec/models.rb), data files in `spec/data/`.
|
|
36
|
-
|
|
37
|
-
### Testing Against Multiple ActiveRecord Versions
|
|
38
|
-
|
|
39
|
-
The gem supports ActiveRecord 6.0-8.0. Uses Appraisal for multi-version testing:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
bundle exec appraisal install # Install all gemfiles
|
|
43
|
-
bundle exec appraisal rspec # Run specs against all versions
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
See `Appraisals` file and `gemfiles/` directory.
|
|
47
|
-
|
|
48
|
-
### Code Style
|
|
49
|
-
|
|
50
|
-
Uses Standard Ruby formatter:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
bundle exec rake standard:fix # Auto-fix style issues
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Critical Patterns
|
|
57
|
-
|
|
58
|
-
### Named Instance Method Generation
|
|
59
|
-
|
|
60
|
-
**Hash-based data files** trigger dynamic method generation. Example from [spec/data/colors/named_colors.yml](spec/data/colors/named_colors.yml):
|
|
61
|
-
|
|
62
|
-
```yaml
|
|
63
|
-
red:
|
|
64
|
-
id: 1
|
|
65
|
-
name: Red
|
|
66
|
-
value: 16711680
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Generates:
|
|
70
|
-
- `Color.red` → finds record by id
|
|
71
|
-
- `color_instance.red?` → tests if `color_instance.id == 1`
|
|
72
|
-
- `Color.red_id` → returns `1` (if `named_instance_attribute_helpers :id` defined)
|
|
73
|
-
|
|
74
|
-
**Implementation**: See `define_support_table_named_instance_methods` in [lib/support_table_data.rb](lib/support_table_data.rb#L230-L265). Methods are generated using `class_eval` with string interpolation.
|
|
75
|
-
|
|
76
|
-
### Custom Setters for Associations
|
|
77
|
-
|
|
78
|
-
Support tables often reference other support tables via named instances. Pattern from [spec/models.rb](spec/models.rb#L72-L74):
|
|
79
|
-
|
|
80
|
-
```ruby
|
|
81
|
-
def group_name=(value)
|
|
82
|
-
self.group = Group.named_instance(value)
|
|
83
|
-
end
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Allows data files to reference related records by instance name instead of foreign keys.
|
|
87
|
-
|
|
88
|
-
### Key Attribute Configuration
|
|
89
|
-
|
|
90
|
-
By default, uses model's `id` column. Override for non-id keys:
|
|
91
|
-
|
|
92
|
-
```ruby
|
|
93
|
-
self.support_table_key_attribute = :name # Use 'name' instead of 'id'
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
Key attributes cannot be updated—changing them creates new records.
|
|
97
|
-
|
|
98
|
-
### Dependency Resolution
|
|
99
|
-
|
|
100
|
-
`sync_all!` automatically resolves dependencies via `belongs_to` associations and loads tables in correct order. For complex cases (join tables, indirect dependencies), explicitly declare:
|
|
101
|
-
|
|
102
|
-
```ruby
|
|
103
|
-
support_table_dependency "OtherModel"
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
See [lib/support_table_data.rb](lib/support_table_data.rb#L219-L222) and dependency resolution logic.
|
|
107
|
-
|
|
108
|
-
## Testing Conventions
|
|
109
|
-
|
|
110
|
-
- **Test data isolation**: Each test deletes all records in `before` block ([spec/spec_helper.rb](spec/spec_helper.rb))
|
|
111
|
-
- **Sync before assertions**: Tests call `sync_table_data!` or `sync_all!` before verifying records exist
|
|
112
|
-
- **Multi-file merging**: Tests verify that multiple data files for same model merge correctly (see `Color` model with 5 data files)
|
|
113
|
-
- **STI handling**: See `Polygon`/`Triangle`/`Rectangle` tests for Single Table Inheritance patterns
|
|
114
|
-
|
|
115
|
-
## Common Pitfalls
|
|
116
|
-
|
|
117
|
-
1. **Method name conflicts**: Named instance methods raise `ArgumentError` if method already exists. Instance names must match `/\A[a-z][a-z0-9_]+\z/`
|
|
118
|
-
2. **Array vs hash data**: Only hash-keyed data generates named instance methods. Use arrays or underscore-prefixed keys (`_others`) for records without helpers
|
|
119
|
-
3. **Protected instances**: Records in data files cannot be deleted via `destroy` (though this gem doesn't enforce it—see companion caching gem)
|
|
120
|
-
4. **Transaction safety**: All sync operations wrapped in transactions; changes rollback on failure
|
|
121
|
-
|
|
122
|
-
## Rails Integration
|
|
123
|
-
|
|
124
|
-
In Rails apps, the gem automatically:
|
|
125
|
-
- Sets `SupportTableData.data_directory` to `Rails.root/db/support_tables`
|
|
126
|
-
- Provides `rake support_table_data:sync` task ([lib/tasks/support_table_data.rake](lib/tasks/support_table_data.rake))
|
|
127
|
-
- Handles eager loading in both classic and Zeitwerk autoloaders
|
|
128
|
-
|
|
129
|
-
## File References
|
|
130
|
-
|
|
131
|
-
- Main module: [lib/support_table_data.rb](lib/support_table_data.rb)
|
|
132
|
-
- Test models: [spec/models.rb](spec/models.rb) - comprehensive examples of patterns
|
|
133
|
-
- Sync task: [lib/tasks/support_table_data.rake](lib/tasks/support_table_data.rake)
|
|
134
|
-
- Architecture docs: [ARCHITECTURE.md](ARCHITECTURE.md) - detailed diagrams and design decisions
|
|
135
|
-
|
|
136
|
-
## Version Compatibility
|
|
137
|
-
|
|
138
|
-
- Ruby ≥ 2.5
|
|
139
|
-
- ActiveRecord ≥ 6.0
|
|
140
|
-
- Ruby 3.4+: Requires `csv` gem in Gemfile (removed from stdlib)
|