support_table_data 1.4.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/ARCHITECTURE.md +538 -0
  3. data/CHANGELOG.md +21 -0
  4. data/README.md +52 -5
  5. data/VERSION +1 -1
  6. data/lib/support_table_data/documentation/source_file.rb +98 -0
  7. data/lib/support_table_data/documentation/yard_doc.rb +91 -0
  8. data/lib/support_table_data/documentation.rb +9 -0
  9. data/lib/support_table_data/railtie.rb +22 -1
  10. data/lib/support_table_data/validation_error.rb +16 -0
  11. data/lib/support_table_data.rb +71 -53
  12. data/lib/tasks/support_table_data.rake +61 -12
  13. data/lib/tasks/utils.rb +71 -0
  14. data/support_table_data.gemspec +2 -1
  15. data/test_app/.gitignore +4 -0
  16. data/test_app/Gemfile +7 -0
  17. data/test_app/Rakefile +6 -0
  18. data/test_app/app/models/application_record.rb +5 -0
  19. data/test_app/app/models/secondary_application_record.rb +7 -0
  20. data/test_app/app/models/status.rb +120 -0
  21. data/test_app/app/models/thing.rb +10 -0
  22. data/test_app/bin/rails +4 -0
  23. data/test_app/config/application.rb +42 -0
  24. data/test_app/config/boot.rb +3 -0
  25. data/test_app/config/database.yml +17 -0
  26. data/test_app/config/environment.rb +5 -0
  27. data/test_app/config/environments/development.rb +11 -0
  28. data/test_app/config/environments/test.rb +11 -0
  29. data/test_app/config.ru +6 -0
  30. data/test_app/db/migrate/20260103060951_create_status.rb +8 -0
  31. data/test_app/db/schema.rb +20 -0
  32. data/test_app/db/secondary_migrate/20260104000001_create_things.rb +7 -0
  33. data/test_app/db/secondary_schema.rb +25 -0
  34. data/test_app/db/support_tables/statuses.yml +19 -0
  35. data/test_app/db/support_tables/things.yml +5 -0
  36. data/test_app/lib/tasks/database.rake +11 -0
  37. data/test_app/log/.keep +0 -0
  38. metadata +33 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57189f00e55af0f6d3476edbe8921bfb7ba341fa9a1c6e51eb0674e66327bd12
4
- data.tar.gz: f80d9a8f7ce4877aec13c5f0151ddc017bbcb94ea4b85b2c404b23161d11aaf8
3
+ metadata.gz: '081b2612659ea90591ecf5fd7386acbb9d10dbd90c20301e12fba39d3d81e4b3'
4
+ data.tar.gz: b7d4960153f4799031127c8e2fb6ffaa5da49acc1e59833b64c9f417dd9d77df
5
5
  SHA512:
6
- metadata.gz: df96d9b761bb03c2ddc9bc915bc5441c24f8bf06e20f53fb2d962ae74c19f6828f84f3b4c3f5c1fe6766bceed05c4e64ec6ae458c64c9e6bf549855b4a492222
7
- data.tar.gz: 820ebdea69220e6a03c5b0966138285af9c7e3181c73532917d074c392cc0a708d5bb4c67d0d11f937ef0ffd81e828f226f64aa0a632ec7475578d8edc2a53d6
6
+ metadata.gz: e38a2f56f37888a737c8493ec0078666cf8a138415326946829c506a57fc81f5bc3e8407232e7bacbd82a5d0066d9513dd14340360e9d4179a3b1d51a7d69517
7
+ data.tar.gz: 569bbabe38749923686c5d9aa757851f6ba3fad64317f18e3fdb209aec9c714ed1f020a6c07a1588464d1ed9c129bb983ae25d5378ae324b0abee8e467e0fa96
data/ARCHITECTURE.md ADDED
@@ -0,0 +1,538 @@
1
+ # Support Table Data Architecture
2
+
3
+ This document describes the architecture and design patterns of the `support_table_data` gem, which provides a robust solution for managing static support tables (lookup tables) in ActiveRecord applications.
4
+
5
+ ## Overview
6
+
7
+ The SupportTableData gem solves the common problem of managing small, canonical datasets that exist at the intersection of data and code. These support tables contain a limited number of rows with values that are often referenced in application logic, making them critical for proper application function.
8
+
9
+ ## Core Components
10
+
11
+ ### Main Components Overview
12
+
13
+ ```mermaid
14
+ flowchart TB
15
+ subgraph "Application Layer"
16
+ Model[ActiveRecord Model]
17
+ DataFiles[Data Files<br/>YAML/JSON/CSV]
18
+ end
19
+
20
+ subgraph "SupportTableData Gem"
21
+ Concern[SupportTableData Module]
22
+ Parser[File Parser]
23
+ Sync[Data Synchronizer]
24
+ Helpers[Helper Methods]
25
+ end
26
+
27
+ subgraph "Infrastructure"
28
+ DB[(Database)]
29
+ Rails[Rails Environment]
30
+ Rake[Rake Tasks]
31
+ end
32
+
33
+ Model --> Concern
34
+ DataFiles --> Parser
35
+ Parser --> Sync
36
+ Sync --> DB
37
+ Concern --> Helpers
38
+ Rails --> Rake
39
+ Rake --> Sync
40
+
41
+ style Concern fill:#e1f5fe
42
+ style DataFiles fill:#f3e5f5
43
+ style DB fill:#e8f5e8
44
+ ```
45
+
46
+ ## Data Flow Architecture
47
+
48
+ The gem follows a clear data flow pattern from static files to database records:
49
+
50
+ ```mermaid
51
+ flowchart LR
52
+ subgraph "Source Data"
53
+ YML[YAML Files]
54
+ JSON[JSON Files]
55
+ CSV[CSV Files]
56
+ end
57
+
58
+ subgraph "Processing"
59
+ Parse[File Parser]
60
+ Validate[Data Validation]
61
+ Transform[Data Transformation]
62
+ end
63
+
64
+ subgraph "Storage"
65
+ Memory[In-Memory Cache]
66
+ DB[(Database Tables)]
67
+ end
68
+
69
+ subgraph "Usage"
70
+ Helpers[Helper Methods]
71
+ Queries[Database Queries]
72
+ Predicates[Predicate Methods]
73
+ end
74
+
75
+ YML --> Parse
76
+ JSON --> Parse
77
+ CSV --> Parse
78
+ Parse --> Validate
79
+ Validate --> Transform
80
+ Transform --> Memory
81
+ Transform --> DB
82
+ Memory --> Helpers
83
+ DB --> Queries
84
+ Helpers --> Predicates
85
+
86
+ style Parse fill:#fff3e0
87
+ style DB fill:#e8f5e8
88
+ style Helpers fill:#e3f2fd
89
+ ```
90
+
91
+ ## Class Structure
92
+
93
+ ### Core Module Design
94
+
95
+ ```mermaid
96
+ classDiagram
97
+ class SupportTableData {
98
+ +data_directory : String
99
+ +sync_all!() : Hash
100
+ +support_table_classes() : Array
101
+ }
102
+
103
+ class ActiveRecord_Model {
104
+ +support_table_key_attribute : String
105
+ +support_table_data_directory : String
106
+ +add_support_table_data(path)
107
+ +sync_table_data!() : Array
108
+ +named_instance(name) : Record
109
+ +instance_names() : Array
110
+ +protected_instance?(record) : Boolean
111
+ }
112
+
113
+ class NamedInstanceHelpers {
114
+ +class_name() : Record
115
+ +class_name_question() : Boolean
116
+ +class_name_attribute() : Value
117
+ }
118
+
119
+ class FileParser {
120
+ +parse_yaml(content) : Hash
121
+ +parse_json(content) : Hash
122
+ +parse_csv(content) : Array
123
+ }
124
+
125
+ class DataSynchronizer {
126
+ +sync_records(data) : Array
127
+ +create_record(attributes) : Record
128
+ +update_record(record, attributes) : Record
129
+ }
130
+
131
+ SupportTableData --> ActiveRecord_Model : extends
132
+ ActiveRecord_Model --> NamedInstanceHelpers : generates
133
+ ActiveRecord_Model --> FileParser : uses
134
+ ActiveRecord_Model --> DataSynchronizer : uses
135
+
136
+ note for NamedInstanceHelpers "Methods are dynamically generated based on data file content"
137
+ ```
138
+
139
+ ## Named Instance System
140
+
141
+ The gem's most powerful feature is its named instance system, which generates helper methods from data files:
142
+
143
+ ```mermaid
144
+ flowchart TD
145
+ subgraph "Data File Structure"
146
+ HashData[Hash-based Data]
147
+ ArrayData[Array-based Data]
148
+ end
149
+
150
+ subgraph "Method Generation"
151
+ ClassMethods[Class Methods<br/>Status.pending]
152
+ InstanceMethods[Instance Methods<br/>status.pending?]
153
+ AttributeHelpers[Attribute Helpers<br/>Status.pending_id]
154
+ end
155
+
156
+ subgraph "Runtime Usage"
157
+ FindRecord[Find Specific Record]
158
+ TestRecord[Test Record Type]
159
+ GetAttribute[Get Static Attribute]
160
+ end
161
+
162
+ HashData --> ClassMethods
163
+ HashData --> InstanceMethods
164
+ ArrayData --> ClassMethods
165
+ ClassMethods --> FindRecord
166
+ InstanceMethods --> TestRecord
167
+ AttributeHelpers --> GetAttribute
168
+
169
+ style HashData fill:#f3e5f5
170
+ style ClassMethods fill:#e3f2fd
171
+ style InstanceMethods fill:#e8f5e8
172
+ ```
173
+
174
+ ## Data Synchronization Process
175
+
176
+ The synchronization process ensures database consistency with data files:
177
+
178
+ ```mermaid
179
+ sequenceDiagram
180
+ participant App as Application
181
+ participant Model as AR Model
182
+ participant Parser as File Parser
183
+ participant DB as Database
184
+
185
+ App->>Model: sync_table_data!
186
+ Model->>Parser: Parse data files
187
+ Parser-->>Model: Canonical data
188
+
189
+ Model->>DB: BEGIN TRANSACTION
190
+ Model->>DB: Find existing records
191
+ DB-->>Model: Current records
192
+
193
+ loop For each record
194
+ Model->>Model: Compare attributes
195
+ alt Record changed
196
+ Model->>DB: UPDATE record
197
+ end
198
+ end
199
+
200
+ loop For new records
201
+ Model->>DB: INSERT record
202
+ end
203
+
204
+ Model->>DB: COMMIT TRANSACTION
205
+ Model-->>App: Changes summary
206
+ ```
207
+
208
+ ## File Format Support
209
+
210
+ The gem supports multiple data file formats with a unified interface:
211
+
212
+ ```mermaid
213
+ flowchart LR
214
+ subgraph "Input Formats"
215
+ YAML[YAML<br/>*.yml, *.yaml]
216
+ JSON[JSON<br/>*.json]
217
+ CSV[CSV<br/>*.csv]
218
+ end
219
+
220
+ subgraph "Parser Layer"
221
+ YAMLParser[YAML::safe_load]
222
+ JSONParser[JSON::parse]
223
+ CSVParser[CSV Parser<br/>with headers]
224
+ end
225
+
226
+ subgraph "Output Format"
227
+ Hash[Hash Structure<br/>Named instances]
228
+ Array[Array Structure<br/>Simple records]
229
+ end
230
+
231
+ YAML --> YAMLParser
232
+ JSON --> JSONParser
233
+ CSV --> CSVParser
234
+
235
+ YAMLParser --> Hash
236
+ YAMLParser --> Array
237
+ JSONParser --> Hash
238
+ JSONParser --> Array
239
+ CSVParser --> Array
240
+
241
+ style YAML fill:#e8f5e8
242
+ style JSON fill:#fff3e0
243
+ style CSV fill:#f3e5f5
244
+ ```
245
+
246
+ ## Dependency Resolution
247
+
248
+ The gem automatically resolves dependencies between support table models:
249
+
250
+ ```mermaid
251
+ flowchart TB
252
+ subgraph "Dependency Analysis"
253
+ Belongs[belongs_to Associations]
254
+ Explicit[Explicit Dependencies]
255
+ Through[has_many :through]
256
+ end
257
+
258
+ subgraph "Resolution Strategy"
259
+ Detect[Detect Dependencies]
260
+ Sort[Topological Sort]
261
+ Validate[Circular Detection]
262
+ end
263
+
264
+ subgraph "Load Order"
265
+ Level1[Independent Models]
266
+ Level2[Models with Dependencies]
267
+ Level3[Join Table Models]
268
+ end
269
+
270
+ Belongs --> Detect
271
+ Explicit --> Detect
272
+ Through --> Detect
273
+
274
+ Detect --> Sort
275
+ Sort --> Validate
276
+ Validate --> Level1
277
+ Level1 --> Level2
278
+ Level2 --> Level3
279
+
280
+ style Detect fill:#e3f2fd
281
+ style Sort fill:#f3e5f5
282
+ style Level1 fill:#e8f5e8
283
+ ```
284
+
285
+ ## Rails Integration
286
+
287
+ The gem integrates seamlessly with Rails applications:
288
+
289
+ ```mermaid
290
+ flowchart TD
291
+ subgraph "Rails Boot Process"
292
+ Boot[Application Boot]
293
+ Eager[Eager Loading]
294
+ Routes[Routes Loading]
295
+ end
296
+
297
+ subgraph "Gem Integration"
298
+ Railtie[SupportTableData::Railtie]
299
+ Tasks[Rake Tasks]
300
+ AutoLoad[Auto Discovery]
301
+ end
302
+
303
+ subgraph "Development Workflow"
304
+ Migrate[db:migrate]
305
+ Sync[support_table_data:sync]
306
+ Test[Test Suite Setup]
307
+ end
308
+
309
+ Boot --> Railtie
310
+ Eager --> AutoLoad
311
+ Railtie --> Tasks
312
+ Tasks --> Sync
313
+ Migrate --> Sync
314
+ Sync --> Test
315
+
316
+ style Railtie fill:#e3f2fd
317
+ style Sync fill:#e8f5e8
318
+ style Test fill:#fff3e0
319
+ ```
320
+
321
+ ## Error Handling and Validation
322
+
323
+ The gem includes comprehensive error handling:
324
+
325
+ ```mermaid
326
+ flowchart TD
327
+ subgraph "Validation Points"
328
+ FileFormat[File Format Validation]
329
+ DataStructure[Data Structure Validation]
330
+ MethodNames[Method Name Validation]
331
+ KeyAttributes[Key Attribute Validation]
332
+ end
333
+
334
+ subgraph "Error Types"
335
+ ParseError[File Parse Errors]
336
+ NameError[Method Name Conflicts]
337
+ DataError[Data Consistency Errors]
338
+ TransactionError[Database Transaction Errors]
339
+ end
340
+
341
+ subgraph "Recovery Strategies"
342
+ Rollback[Transaction Rollback]
343
+ ErrorReport[Detailed Error Messages]
344
+ PartialSync[Skip Invalid Records]
345
+ end
346
+
347
+ FileFormat --> ParseError
348
+ DataStructure --> DataError
349
+ MethodNames --> NameError
350
+ KeyAttributes --> DataError
351
+
352
+ ParseError --> ErrorReport
353
+ NameError --> ErrorReport
354
+ DataError --> Rollback
355
+ TransactionError --> Rollback
356
+
357
+ style ParseError fill:#ffebee
358
+ style Rollback fill:#e8f5e8
359
+ style ErrorReport fill:#fff3e0
360
+ ```
361
+
362
+ ## Performance Considerations
363
+
364
+ The gem is designed for optimal performance with small datasets:
365
+
366
+ ```mermaid
367
+ flowchart LR
368
+ subgraph "Optimization Strategies"
369
+ SmallData[Small Dataset Focus<br/>&lt; 100 records]
370
+ Memoization[Method Memoization]
371
+ Transaction[Atomic Transactions]
372
+ LazyLoad[Lazy Method Generation]
373
+ end
374
+
375
+ subgraph "Memory Management"
376
+ ClassVars[Class Variables]
377
+ Mutex[Thread Safety]
378
+ WeakRef[Weak References]
379
+ end
380
+
381
+ subgraph "Database Efficiency"
382
+ BulkOps[Bulk Operations]
383
+ IndexHints[Key Attribute Indexing]
384
+ MinQueries[Minimize Queries]
385
+ end
386
+
387
+ SmallData --> ClassVars
388
+ Memoization --> Mutex
389
+ Transaction --> BulkOps
390
+ LazyLoad --> WeakRef
391
+
392
+ ClassVars --> MinQueries
393
+ Mutex --> IndexHints
394
+ BulkOps --> MinQueries
395
+
396
+ style SmallData fill:#e8f5e8
397
+ style Transaction fill:#e3f2fd
398
+ style MinQueries fill:#fff3e0
399
+ ```
400
+
401
+ ## Extension Points
402
+
403
+ The gem provides several extension points for customization:
404
+
405
+ ```mermaid
406
+ flowchart TB
407
+ subgraph "Customization Options"
408
+ KeyAttr[Custom Key Attributes]
409
+ DataDir[Custom Data Directories]
410
+ Parser[Custom File Parsers]
411
+ Validation[Custom Validations]
412
+ end
413
+
414
+ subgraph "Integration Hooks"
415
+ BeforeSync[Before Sync Callbacks]
416
+ AfterSync[After Sync Callbacks]
417
+ MethodGen[Method Generation Hooks]
418
+ ErrorHook[Error Handling Hooks]
419
+ end
420
+
421
+ subgraph "External Gems"
422
+ Cache[SupportTableCache]
423
+ Observers[ActiveRecord Observers]
424
+ Auditing[Auditing Gems]
425
+ end
426
+
427
+ KeyAttr --> BeforeSync
428
+ DataDir --> MethodGen
429
+ Parser --> ErrorHook
430
+ Validation --> AfterSync
431
+
432
+ BeforeSync --> Cache
433
+ MethodGen --> Observers
434
+ ErrorHook --> Auditing
435
+
436
+ style Cache fill:#e3f2fd
437
+ style BeforeSync fill:#f3e5f5
438
+ style MethodGen fill:#e8f5e8
439
+ ```
440
+
441
+ ## Deployment Strategy
442
+
443
+ The gem follows a deployment-friendly pattern:
444
+
445
+ ```mermaid
446
+ flowchart LR
447
+ subgraph "Development"
448
+ DevData[Dev Data Files]
449
+ DevDB[Dev Database]
450
+ DevTest[Test Suite]
451
+ end
452
+
453
+ subgraph "CI/CD Pipeline"
454
+ Build[Build Process]
455
+ Migration[Run Migrations]
456
+ DataSync[Sync Support Data]
457
+ TestRun[Run Tests]
458
+ end
459
+
460
+ subgraph "Production"
461
+ ProdDB[Production Database]
462
+ ProdData[Production Data]
463
+ Monitor[Monitoring]
464
+ end
465
+
466
+ DevData --> Build
467
+ DevDB --> Migration
468
+ DevTest --> TestRun
469
+
470
+ Build --> Migration
471
+ Migration --> DataSync
472
+ DataSync --> TestRun
473
+ TestRun --> ProdDB
474
+
475
+ ProdDB --> ProdData
476
+ ProdData --> Monitor
477
+
478
+ style DataSync fill:#e8f5e8
479
+ style TestRun fill:#e3f2fd
480
+ style Monitor fill:#fff3e0
481
+ ```
482
+
483
+ ## Best Practices
484
+
485
+ ### Model Organization
486
+
487
+ ```mermaid
488
+ flowchart TD
489
+ subgraph "File Structure"
490
+ Models[app/models/]
491
+ DataFiles[db/support_tables/]
492
+ Tests[spec/models/]
493
+ end
494
+
495
+ subgraph "Naming Conventions"
496
+ ModelFile[status.rb]
497
+ DataFile[statuses.yml]
498
+ TestFile[status_spec.rb]
499
+ end
500
+
501
+ subgraph "Content Organization"
502
+ Includes[Include SupportTableData]
503
+ Config[Configure Directories]
504
+ AddData[Add Data Files]
505
+ Helpers[Define Helpers]
506
+ end
507
+
508
+ Models --> ModelFile
509
+ DataFiles --> DataFile
510
+ Tests --> TestFile
511
+
512
+ ModelFile --> Includes
513
+ DataFile --> Config
514
+ TestFile --> AddData
515
+ Config --> Helpers
516
+
517
+ style ModelFile fill:#e3f2fd
518
+ style DataFile fill:#f3e5f5
519
+ style Includes fill:#e8f5e8
520
+ ```
521
+
522
+ ## Summary
523
+
524
+ The SupportTableData gem provides a comprehensive solution for managing static support tables through:
525
+
526
+ 1. **Declarative Configuration**: Define support data in version-controlled files
527
+ 2. **Automatic Synchronization**: Keep database records in sync with data files
528
+ 3. **Generated Helper Methods**: Clean, readable code for accessing specific records
529
+ 4. **Dependency Management**: Automatic resolution of inter-table dependencies
530
+ 5. **Rails Integration**: Seamless integration with Rails applications and deployment workflows
531
+ 6. **Type Safety**: Compile-time method generation with runtime validation
532
+ 7. **Performance**: Optimized for small datasets with minimal overhead
533
+
534
+ The architecture promotes maintainable code by keeping support data close to the application logic while ensuring data consistency across environments.
535
+
536
+ <function_calls>
537
+ <invoke name="get-syntax-docs-mermaid">
538
+ <parameter name="file">flowchart.md
data/CHANGELOG.md CHANGED
@@ -4,6 +4,27 @@ 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
+
15
+ ## 1.5.0
16
+
17
+ ### Added
18
+
19
+ - The default data directory in a Rails application can be set with the `config.support_table.data_directory` option in the Rails application configuration.
20
+ - Added rake task `support_table_data:yard_docs:add` for Rails applications that will add YARD documentation to support table models for the named instance helpers. There is also a task `support_table_data:yard_docs:verify` that can be used in a build pipeline to verify that the documentation is up to date. You can also remove the documentation with the `support_table_data:yard_docs:remove` task.
21
+ - The data synchronization task is now automatically attached to several Rails tasks: `db:seed`, `db:seed:replant`, `db:prepare`, `db:test:prepare`, `db:fixtures:load`. Support tables will be synced after running any of these tasks. This can be disabled by setting `config.support_table.auto_sync = false` in the Rails application configuration.
22
+
23
+ ### Changed
24
+
25
+ - The default data directory is now set in a Railtie and can be overridden with the `config.support_table.data_directory` option in the Rails application configuration.
26
+ - The `support_table_key_attribute` method now returns "id" if not explicitly set instead of implicitly interpreting `nil` as the primary key. This makes the behavior more consistent and explicit and avoids edge cases when running the code in environments where the database connection is not available. This is a breaking change if the table uses a primary key other than "id" and the `support_table_key_attribute` was not explicitly set to that primary key.
27
+
7
28
  ## 1.4.0
8
29
 
9
30
  ### Fixed
data/README.md CHANGED
@@ -8,6 +8,19 @@ This gem provides a mixin for ActiveRecord support table models that allows you
8
8
 
9
9
  These kinds of models blur the line between data and code. You'll often end up with constants and application logic based on specific values that need to exist in the table. By using this gem, you can easily define methods for loading and comparing specific instances. This can give you cleaner code that reads far more naturally. You can also avoid defining dozens of constants or referencing magic values (i.e. no more hard-coded strings or ids in the code to look up specific records).
10
10
 
11
+ ## Table of Contents
12
+
13
+ - [Usage](#usage)
14
+ - [Specifying Data Files](#specifying-data-files)
15
+ - [Named Instances](#named-instances)
16
+ - [Documenting Named Instance Helpers](#documenting-named-instance-helpers)
17
+ - [Caching](#caching)
18
+ - [Loading Data](#loading-data)
19
+ - [Testing](#testing)
20
+ - [Installation](#installation)
21
+ - [Contributing](#contributing)
22
+ - [License](#license)
23
+
11
24
  ## Usage
12
25
 
13
26
  In the examples below, suppose we have a simple `Status` model in which each row has an id and a name, and the name can only have a handful of statuses: "Pending", "In Progress", and "Completed".
@@ -55,7 +68,9 @@ class Status < ApplicationRecord
55
68
 
56
69
  You cannot update the value of the key attribute in a record in the data file. If you do, a new record will be created and the existing record will be left unchanged.
57
70
 
58
- You can specify data files as relative paths. This can be done by setting the `SupportTableData.data_directory` value. You can override this value for a model by setting the `support_table_data_directory` attribute on its class. In a Rails application, `SupportTableData.data_directory` will be automatically set to `db/support_tables/`. Otherwise, relative file paths will be resolved from the current working directory. You must define the directory to load relative files from before loading your model classes.
71
+ You can specify data files as relative paths. This can be done by setting the `SupportTableData.data_directory` value. You can override this value for a model by setting the `support_table_data_directory` attribute on its class. Otherwise, relative file paths will be resolved from the current working directory. You must define the directory to load relative files from before loading your model classes.
72
+
73
+ In a Rails application, `SupportTableData.data_directory` will be automatically set to `db/support_tables/`. This can be overridden by setting the `config.support_table.data_directory` option in the Rails application configuration.
59
74
 
60
75
  **Note**: If you're using CSV files and Ruby 3.4 or higher, you'll need to include the `csv` gem in your Gemfile since it was removed from the standard library in Ruby 3.4.
61
76
 
@@ -109,7 +124,6 @@ Helper methods will not override already defined methods on a model class. If a
109
124
 
110
125
  You can also define helper methods for named instance attributes. These helper methods will return the hard coded values from the data file. Calling these methods does not require a database connection.
111
126
 
112
-
113
127
  ```ruby
114
128
  class Status < ApplicationRecord
115
129
  include SupportTableData
@@ -171,6 +185,21 @@ completed:
171
185
  group_name: done
172
186
  ```
173
187
 
188
+ #### Documenting Named Instance Helpers
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`. 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]"`.
193
+
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.
195
+
196
+ ```ruby
197
+ # Begin YARD docs for support_table_data
198
+ # End YARD docs for support_table_data
199
+ ```
200
+
201
+ A good practice is to add a check to your CI pipeline to ensure the documentation is always up to date. You can run the rake task `support_table_data:yard_docs:verify` to do this. It will exit with an error if any models do not have up to date documentation.
202
+
174
203
  ### Caching
175
204
 
176
205
  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.
@@ -198,6 +227,9 @@ class Thing < ApplicationRecord
198
227
  end
199
228
  ```
200
229
 
230
+ > [!TIP]
231
+ > The [support_table](https://github.com/bdurand/support_table) gem combines both gems in a drop in solution for Rails applications.
232
+
201
233
  ### Loading Data
202
234
 
203
235
  Calling `sync_table_data!` on your model class will synchronize the data in the database table with the values from the data files.
@@ -246,18 +278,33 @@ end
246
278
 
247
279
  If you use a method to set a `has_many` association on your model, you **must** set the `autosave` option to `true` on the association (see the above example). This will ensure the association records are always saved even if there were no changes to the parent record.
248
280
 
249
- 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:
281
+ You will need to call `SupportTableData.sync_all!` when deploying your application or running your test suite. This gem includes a rake task `support_table_data:sync` that is suitable for hooking into deploy or CI scripts.
282
+
283
+ This task is automatically run whenever you run any of these Rails tasks so if these are already part of your deploy or CI scripts, then no additional setup is required:
284
+
285
+ - `db:seed`
286
+ - `db:seed:replant`
287
+ - `db:prepare`
288
+ - `db:test:prepare`
289
+ - `db:fixtures:load`
290
+
291
+ You can disable these task enhancements by setting `config.support_table.auto_sync = false` in your Rails application configuration.
292
+
293
+ > [!TIP]
294
+ > If you also want to hook into the `db:migrate` task so that syncs are run immediately after database migrations, you can do this by adding code to a Rakefile in your application's `lib/tasks` directory. Migrations do funny things with the database connection especially when using multiple databases so you need to re-establish the connection before syncing the support table data.
250
295
 
251
296
  ```ruby
252
297
  if Rake::Task.task_defined?("db:migrate")
253
298
  Rake::Task["db:migrate"].enhance do
299
+ # The main database connection may have artifacts from the migration, so re-establish it
300
+ # to get a clean connection before syncing support table data.
301
+ ActiveRecord::Base.establish_connection
302
+
254
303
  Rake::Task["support_table_data:sync"].invoke
255
304
  end
256
305
  end
257
306
  ```
258
307
 
259
- Enhancing the `db:migrate` task also ensures that local development environments will stay up to date.
260
-
261
308
  ### Testing
262
309
 
263
310
  You must also call `SupportTableData.sync_all!` before running your test suite. This method should be called in the test suite setup code after any data in the test database has been purged and before any tests are run.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.1