support_table_data 1.5.2 → 1.6.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +54 -1
  4. data/VERSION +1 -1
  5. data/lib/support_table_data/documentation/rbs_doc.rb +52 -0
  6. data/lib/support_table_data/documentation/rbs_file.rb +104 -0
  7. data/lib/support_table_data/documentation/source_file.rb +3 -1
  8. data/lib/support_table_data/documentation/type_inference.rb +57 -0
  9. data/lib/support_table_data/documentation/yard_doc.rb +99 -8
  10. data/lib/support_table_data/documentation.rb +5 -3
  11. data/lib/{tasks → support_table_data/tasks}/utils.rb +12 -1
  12. data/lib/support_table_data/tasks.rb +7 -0
  13. data/lib/support_table_data.rb +67 -7
  14. data/lib/tasks/support_table_data.rake +51 -12
  15. data/support_table_data.gemspec +1 -0
  16. metadata +7 -26
  17. data/test_app/.gitignore +0 -4
  18. data/test_app/Gemfile +0 -7
  19. data/test_app/Rakefile +0 -6
  20. data/test_app/app/models/application_record.rb +0 -5
  21. data/test_app/app/models/secondary_application_record.rb +0 -7
  22. data/test_app/app/models/status.rb +0 -120
  23. data/test_app/app/models/thing.rb +0 -10
  24. data/test_app/bin/rails +0 -4
  25. data/test_app/config/application.rb +0 -42
  26. data/test_app/config/boot.rb +0 -3
  27. data/test_app/config/database.yml +0 -17
  28. data/test_app/config/environment.rb +0 -5
  29. data/test_app/config/environments/development.rb +0 -11
  30. data/test_app/config/environments/test.rb +0 -11
  31. data/test_app/config.ru +0 -6
  32. data/test_app/db/migrate/20260103060951_create_status.rb +0 -8
  33. data/test_app/db/schema.rb +0 -20
  34. data/test_app/db/secondary_migrate/20260104000001_create_things.rb +0 -7
  35. data/test_app/db/secondary_schema.rb +0 -25
  36. data/test_app/db/support_tables/statuses.yml +0 -19
  37. data/test_app/db/support_tables/things.yml +0 -5
  38. data/test_app/lib/tasks/database.rake +0 -11
  39. data/test_app/log/.keep +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82058731205c6222edf23783def3fdd7034354f9f81b77deb1eab2dd466de423
4
- data.tar.gz: b5cdf88268b861064d5676a67c43ac1ed5d3ea94bf9cabd6ddfa7c5aaa49db4d
3
+ metadata.gz: 6aa6d124e04e60a539f6a56207da866bb6aa0d277484104f6685d9499b41d504
4
+ data.tar.gz: f3c9791bf9e6b2a46416cca2a154abdb1fe18e108f3e386670818939cabac1a2
5
5
  SHA512:
6
- metadata.gz: 051ba76b99aecd331fe2d30779604619dfd3008e4538dfeb2542bce26ae764a498a64b03f47090c3e5cadb71d2a782df868c9749f74a436b47438c67b3c540d7
7
- data.tar.gz: 352daacb10516c249346b2424718136055229c19099e17126a36c66b9a717ca0998f2a9cfab785e05fcffc8fdfa6e543ac853ec19419edafc8fd84f8c8b5ba54
6
+ metadata.gz: cec5bdca6906dac42489e2f43798bf647eebaf6fd1df1d314bb259cf46170c6f7833aeccd7f7d59917ea0406699f6cc99905afc5977bd907c1e19f750dc0b3e5
7
+ data.tar.gz: eb748280d59753b9bde5618900d0f25ae8e01c3ace0a37cdb5021cad1f1751832b14cc6e4bd624b200398178cd8bd3636e5d8d128c829180fe3c547d67ac88db
data/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ 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.6.0
8
+
9
+ ### Added
10
+
11
+ - Added `delete_missing` option to `sync_table_data!` and `sync_all!`. When set to `true`, any records in the database that are not defined in the data files will be deleted. This option defaults to `false` to preserve backward compatibility.
12
+ - Each model can now choose how its YARD docs are generated by setting `self.support_table_yard_docs` to `:full` (the default — verbose comment block per method), `:compact` (shared `@!macro` definitions plus a short `@!method`/`@!macro` pair per method, dramatically reducing comment-block size on tables with many named instances), or `:none` (skip generation entirely; previously generated docs are stripped on the next run). IDEs and `yard doc` resolve the compact form into the same per-method documentation as the verbose form.
13
+ - Attribute helper return types in the generated YARD and RBS docs are now inferred per method by inspecting the value the helper actually returns (`String`, `Integer`, `Boolean`, etc.) instead of the generic `Object`/`untyped`. Because the helpers return frozen literals from the parsed data file, the documentation tasks no longer require a database connection.
14
+ - Added opt-in RBS signature generation. The new tasks `support_table_data:rbs`, `support_table_data:rbs:verify`, and `support_table_data:rbs:remove` write/check/delete `sig/<model_path>.rbs` files so the named instance helpers are visible to Ruby LSP, Steep, RubyMine, and other RBS-aware tools without polluting the model source files. The output directory can be overridden with `SupportTableData.rbs_signatures_path`.
15
+
7
16
  ## 1.5.2
8
17
 
9
18
  ### Added
data/README.md CHANGED
@@ -189,7 +189,7 @@ completed:
189
189
 
190
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
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]"`.
192
+ To update a single model file, use the `add` task and pass an optional file path argument, for example: `bundle exec rake "support_table_data:yard_docs:add[app/models/status.rb]"`.
193
193
 
194
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
195
 
@@ -200,6 +200,30 @@ The default behavior is to add the documentation comments at the end of the mode
200
200
 
201
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
202
 
203
+ Each model can choose how its YARD docs are generated by setting `support_table_yard_docs` to one of three values:
204
+
205
+ - `:full` — verbose comment block per generated method (the default)
206
+ - `:compact` — shared `@!macro` definitions at the top of the documentation block plus a short `@!method` / `@!macro` pair per generated method. IDEs and `yard doc` resolve the macros into the same per-method documentation as `:full`. Useful when a model has many named instances and the verbose comment block is too long to be useful inline.
207
+ - `:none` — generate no YARD docs for this model. The rake task will also strip any previously generated YARD docs from the source file.
208
+
209
+ ```ruby
210
+ class Feature < ApplicationRecord
211
+ include SupportTableData
212
+
213
+ self.support_table_yard_docs = :compact
214
+
215
+ add_support_table_data "features.yml"
216
+ end
217
+ ```
218
+
219
+ Attribute helper return types (`String`, `Integer`, `Boolean`, etc.) are inferred per method by inspecting the value the helper actually returns. The values come straight from the parsed data file, so the documentation tasks do not need a database connection to run.
220
+
221
+ #### Generating RBS Signatures
222
+
223
+ In addition to the inline YARD comments, you can generate [RBS](https://github.com/ruby/rbs) type signatures for the named instance helpers by running `bundle exec rake support_table_data:rbs`. This writes one `sig/<model_path>.rbs` file per model — for example a Rails model at `app/models/feature.rb` produces `sig/app/models/feature.rbs`. The signatures are picked up by Ruby LSP, Steep, RubyMine, and any other RBS-aware tool, and they keep the model source files free of generated content.
224
+
225
+ Just like the YARD task, you can target a single file with `bundle exec rake "support_table_data:rbs:add[app/models/feature.rb]"`, verify they are up to date in CI with `support_table_data:rbs:verify`, and remove the generated files with `support_table_data:rbs:remove`. RBS generation is opt-in — running the YARD task alone does not produce RBS output, and vice versa.
226
+
203
227
  ### Caching
204
228
 
205
229
  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.
@@ -240,6 +264,21 @@ Status.sync_table_data!
240
264
 
241
265
  This will add any missing records to the table and update existing records so that the attributes in the table match the values in the data files. Records that do not appear in the data files will not be touched. Any attributes not specified in the data files will not be changed.
242
266
 
267
+ If you want to remove records from the database that are no longer in the data files, you can pass `delete_missing: true`:
268
+
269
+ ```ruby
270
+ Status.sync_table_data!(delete_missing: true)
271
+ ```
272
+
273
+ This option can also be passed to `SupportTableData.sync_all!`:
274
+
275
+ ```ruby
276
+ SupportTableData.sync_all!(delete_missing: true)
277
+ ```
278
+
279
+ > [!CAUTION]
280
+ > Use `delete_missing` with care. It will delete any records in the table that are not defined in the data files, which may include user-created data or fail due to foreign key constraints.
281
+
243
282
  The number of records contained in data files should be fairly small (ideally fewer than 100). It is possible to load just a subset of rows in a large table because only the rows listed in the data files will be synced. You can use this feature if your table allows user-entered data, but has a few rows that must exist for the code to work.
244
283
 
245
284
  Loading data is done inside a database transaction. No changes will be persisted to the database unless all rows for a model can be synced.
@@ -309,6 +348,20 @@ end
309
348
 
310
349
  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.
311
350
 
351
+ > [!TIP]
352
+ > If you are using a truncation database cleaning strategy exclude the support tables from the tables that get truncated. Syncing data is much faster when the data is already in the database. You should use the `delete_missing` option to remove any records that are not in the data files instead of deleting all records before each test.
353
+
354
+ ```ruby
355
+ # Excluding support tables from truncation in DatabaseCleaner configuration.
356
+ RSpec.configure do |config|
357
+ config.before(:suite) do
358
+ support_tables = SupportTableData.support_table_classes.map(&:table_name)
359
+ DatabaseCleaner.clean_with(:truncation, except: support_tables)
360
+ SupportTableData.sync_all!(delete_missing: true)
361
+ end
362
+ end
363
+ ```
364
+
312
365
  ## Installation
313
366
 
314
367
  Add this line to your application's Gemfile:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.2
1
+ 1.6.0
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SupportTableData
4
+ module Documentation
5
+ # Generates RBS type signatures for the dynamically-defined named instance
6
+ # helper methods on a support table model.
7
+ class RbsDoc
8
+ # @param klass [Class] The model class to generate signatures for
9
+ def initialize(klass)
10
+ @klass = klass
11
+ end
12
+
13
+ # Render the full RBS file content for the model, including the class
14
+ # declaration. Returns nil when the model has no named instances.
15
+ #
16
+ # @return [String, nil]
17
+ def signatures
18
+ instance_names = klass.instance_names
19
+ return nil if instance_names.empty?
20
+
21
+ body_lines = []
22
+ instance_names.sort.each_with_index do |name, idx|
23
+ body_lines << "" unless idx.zero?
24
+ body_lines.concat(instance_signatures(name))
25
+ end
26
+
27
+ <<~RBS
28
+ # Generated by support_table_data - do not edit by hand.
29
+ # To update, run `bundle exec rake support_table_data:rbs`.
30
+ class #{klass.name}
31
+ #{body_lines.map { |line| line.empty? ? "" : " #{line}" }.join("\n")}
32
+ end
33
+ RBS
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :klass
39
+
40
+ def instance_signatures(name)
41
+ lines = []
42
+ lines << "def self.#{name}: () -> #{klass.name}"
43
+ lines << "def #{name}?: () -> bool"
44
+ klass.support_table_attribute_helpers.each do |attribute_name|
45
+ return_type = TypeInference.rbs_type(TypeInference.value_type(klass, "#{name}_#{attribute_name}"))
46
+ lines << "def self.#{name}_#{attribute_name}: () -> #{return_type}"
47
+ end
48
+ lines
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+
5
+ module SupportTableData
6
+ module Documentation
7
+ # Manages reading/writing the per-model RBS signature file.
8
+ class RbsFile
9
+ attr_reader :klass, :source_path, :path
10
+
11
+ # @param klass [Class] The model class
12
+ # @param source_path [Pathname] The path to the model's source `.rb` file
13
+ def initialize(klass, source_path)
14
+ @klass = klass
15
+ @source_path = Pathname.new(source_path)
16
+ @path = self.class.signatures_path_for(@source_path)
17
+ end
18
+
19
+ # Compute where the RBS signatures should live for a given source file.
20
+ # Defaults to `<project_root>/sig/<source_path_minus_extension>.rbs`.
21
+ # The project root is found by walking upward looking for a `Gemfile` or
22
+ # `.git` directory; if neither is found, the immediate parent of the
23
+ # source file is used.
24
+ #
25
+ # @param source_path [Pathname]
26
+ # @return [Pathname]
27
+ def self.signatures_path_for(source_path)
28
+ if SupportTableData.rbs_signatures_path
29
+ base = Pathname.new(SupportTableData.rbs_signatures_path)
30
+ relative = relative_to_project_root(source_path)
31
+ return base.join("#{relative.to_s.sub(/\.rb\z/, "")}.rbs")
32
+ end
33
+
34
+ root = project_root_for(source_path)
35
+ relative = source_path.expand_path.relative_path_from(root)
36
+ root.join("sig", "#{relative.to_s.sub(/\.rb\z/, "")}.rbs")
37
+ end
38
+
39
+ # Project root is the nearest ancestor directory containing a Gemfile or
40
+ # a .git directory. Falls back to the source file's directory.
41
+ def self.project_root_for(source_path)
42
+ current = Pathname.new(source_path).expand_path.parent
43
+ loop do
44
+ return current if current.join("Gemfile").file?
45
+ return current if current.join(".git").exist?
46
+
47
+ parent = current.parent
48
+ return Pathname.new(source_path).expand_path.parent if parent == current
49
+
50
+ current = parent
51
+ end
52
+ end
53
+
54
+ def self.relative_to_project_root(source_path)
55
+ Pathname.new(source_path).expand_path.relative_path_from(project_root_for(source_path))
56
+ end
57
+
58
+ # Render the desired RBS content for this model, or nil if the model has
59
+ # no named instances (in which case no file should be written).
60
+ #
61
+ # @return [String, nil]
62
+ def signatures_content
63
+ RbsDoc.new(klass).signatures
64
+ end
65
+
66
+ # Whether the existing on-disk file matches what would be generated.
67
+ #
68
+ # @return [Boolean]
69
+ def up_to_date?
70
+ desired = signatures_content
71
+ if desired.nil?
72
+ !path.file?
73
+ else
74
+ path.file? && path.read == desired
75
+ end
76
+ end
77
+
78
+ # Write the generated RBS content to disk, creating parent directories as
79
+ # needed. Returns true if the file was written, false if there was nothing
80
+ # to write.
81
+ #
82
+ # @return [Boolean]
83
+ def write!
84
+ content = signatures_content
85
+ return false if content.nil?
86
+
87
+ path.parent.mkpath
88
+ path.write(content)
89
+ true
90
+ end
91
+
92
+ # Delete the generated RBS file if it exists. Returns true if a file was
93
+ # removed.
94
+ #
95
+ # @return [Boolean]
96
+ def remove!
97
+ return false unless path.file?
98
+
99
+ path.delete
100
+ true
101
+ end
102
+ end
103
+ end
104
+ end
@@ -44,7 +44,9 @@ module SupportTableData
44
44
  # @return [String]
45
45
  def source_with_yard_docs
46
46
  yard_docs = YardDoc.new(klass).named_instance_yard_docs
47
- return source if yard_docs.nil?
47
+ if yard_docs.nil?
48
+ return has_yard_docs? ? source_without_yard_docs : source
49
+ end
48
50
 
49
51
  existing_yard_docs = source.match(YARD_COMMENT_REGEX)
50
52
  if existing_yard_docs
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SupportTableData
4
+ module Documentation
5
+ # Infers documentation types for the dynamically-defined attribute helpers
6
+ # by calling the generated method and inspecting the class of the value
7
+ # it returns. The values returned by these helpers are frozen literals from
8
+ # the parsed data file, so this does not require a database connection.
9
+ #
10
+ # This module must not be used on finder helpers (e.g. `Color.red`), which
11
+ # call `find_by!` and would hit the database.
12
+ module TypeInference
13
+ module_function
14
+
15
+ # Determine the documentation type for an attribute helper by calling
16
+ # the method and looking at the class of the returned value. Returns
17
+ # nil when the method is not defined.
18
+ #
19
+ # @param klass [Class] The model class
20
+ # @param method_name [String, Symbol] The class method name to call
21
+ # @return [Class, nil]
22
+ def value_type(klass, method_name)
23
+ return nil unless klass.respond_to?(method_name)
24
+
25
+ klass.public_send(method_name).class
26
+ end
27
+
28
+ # Map a Ruby value class to a YARD type string.
29
+ def yard_type(value_class)
30
+ case value_class&.name
31
+ when "String" then "String"
32
+ when "Integer" then "Integer"
33
+ when "Float" then "Float"
34
+ when "TrueClass", "FalseClass" then "Boolean"
35
+ when "Array" then "Array"
36
+ when "Hash" then "Hash"
37
+ when "NilClass", nil then "Object"
38
+ else value_class.name
39
+ end
40
+ end
41
+
42
+ # Map a Ruby value class to an RBS type string.
43
+ def rbs_type(value_class)
44
+ case value_class&.name
45
+ when "String" then "String"
46
+ when "Integer" then "Integer"
47
+ when "Float" then "Float"
48
+ when "TrueClass", "FalseClass" then "bool"
49
+ when "Array" then "Array[untyped]"
50
+ when "Hash" then "Hash[untyped, untyped]"
51
+ when "NilClass", nil then "untyped"
52
+ else value_class.name
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -3,17 +3,38 @@
3
3
  module SupportTableData
4
4
  module Documentation
5
5
  class YardDoc
6
+ MACRO_FINDER = "support_table_data_finder"
7
+ MACRO_PREDICATE = "support_table_data_predicate"
8
+ MACRO_ATTRIBUTE = "support_table_data_attribute"
9
+
6
10
  # @param klass [Class] The model class to generate documentation for
7
11
  def initialize(klass)
8
12
  @klass = klass
9
13
  end
10
14
 
11
- # Generate YARD documentation class definition for the model's helper methods.
15
+ # Generate YARD documentation for the model's helper methods. The format
16
+ # is controlled by the model's `support_table_yard_docs` setting:
17
+ #
18
+ # * `:full` - verbose comment block per method (default)
19
+ # * `:compact` - shared @!macro definitions plus a short @!method/@!macro
20
+ # pair per generated method
21
+ # * `:none` - generate no docs at all
12
22
  #
13
- # @return [String, nil] The YARD documentation class definition, or nil if no named instances
23
+ # @return [String, nil] The YARD documentation, or nil if no docs should
24
+ # be emitted (either because the model has no named instances or because
25
+ # `support_table_yard_docs` is `:none`).
14
26
  def named_instance_yard_docs
27
+ return nil if klass.support_table_yard_docs == :none
28
+
15
29
  instance_names = klass.instance_names
16
- generate_yard_docs(instance_names)
30
+ return nil if instance_names.empty?
31
+
32
+ case klass.support_table_yard_docs
33
+ when :compact
34
+ generate_compact_yard_docs(instance_names)
35
+ else
36
+ generate_verbose_yard_docs(instance_names)
37
+ end
17
38
  end
18
39
 
19
40
  # Generate YARD documentation comment for named instance singleton method.
@@ -48,14 +69,16 @@ module SupportTableData
48
69
  # Generate YARD documentation comment for the attribute method helper for the named instance.
49
70
  #
50
71
  # @param name [String] The name of the instance method.
72
+ # @param attribute_name [String] The attribute being read.
51
73
  # @return [String] The YARD comment text
52
74
  def attribute_helper_yard_doc(name, attribute_name)
75
+ return_type = attribute_yard_return_type(name, attribute_name)
53
76
  <<~YARD.chomp("\n")
54
77
  # Get the #{attribute_name} attribute from the data file
55
78
  # for the named instance +#{name}+.
56
79
  #
57
80
  # @!method self.#{name}_#{attribute_name}
58
- # @return [Object]
81
+ # @return [#{return_type}]
59
82
  # @!visibility public
60
83
  YARD
61
84
  end
@@ -64,12 +87,9 @@ module SupportTableData
64
87
 
65
88
  attr_reader :klass
66
89
 
67
- def generate_yard_docs(instance_names)
68
- return nil if instance_names.empty?
69
-
90
+ def generate_verbose_yard_docs(instance_names)
70
91
  yard_lines = ["# @!group Named Instances"]
71
92
 
72
- # Generate docs for each named instance
73
93
  instance_names.sort.each do |name|
74
94
  yard_lines << ""
75
95
  yard_lines << instance_helper_yard_doc(name)
@@ -86,6 +106,77 @@ module SupportTableData
86
106
 
87
107
  yard_lines.join("\n")
88
108
  end
109
+
110
+ def generate_compact_yard_docs(instance_names)
111
+ yard_lines = ["# @!group Named Instances"]
112
+ yard_lines << ""
113
+ yard_lines << compact_preamble
114
+ yard_lines << ""
115
+ yard_lines << compact_macro_definitions
116
+
117
+ instance_names.sort.each do |name|
118
+ yard_lines << ""
119
+ yard_lines << compact_instance_block(name)
120
+ end
121
+
122
+ yard_lines << ""
123
+ yard_lines << "# @!endgroup"
124
+
125
+ yard_lines.join("\n")
126
+ end
127
+
128
+ def compact_preamble
129
+ <<~YARD.chomp("\n")
130
+ # The methods in this group are dynamically defined by support_table_data
131
+ # for each named instance in the data file. The macros below are the
132
+ # documentation templates; the per-instance @!method lines that follow
133
+ # invoke them with the instance name (and attribute name, where applicable).
134
+ YARD
135
+ end
136
+
137
+ def compact_macro_definitions
138
+ attribute_macro = <<~YARD.chomp("\n")
139
+ # @!macro [new] #{MACRO_ATTRIBUTE}
140
+ # Get the +$2+ attribute from the data file for the named instance +$1+.
141
+ # @return [$3]
142
+ # @!visibility public
143
+ YARD
144
+
145
+ finder_macro = <<~YARD.chomp("\n")
146
+ # @!macro [new] #{MACRO_FINDER}
147
+ # Find the named instance +$1+ from the database.
148
+ # @return [#{klass.name}]
149
+ # @raise [ActiveRecord::RecordNotFound] if the record does not exist
150
+ # @!visibility public
151
+ YARD
152
+
153
+ predicate_macro = <<~YARD.chomp("\n")
154
+ # @!macro [new] #{MACRO_PREDICATE}
155
+ # Check if this record is the named instance +$1+.
156
+ # @return [Boolean]
157
+ # @!visibility public
158
+ YARD
159
+
160
+ [finder_macro, "", predicate_macro, "", attribute_macro].join("\n")
161
+ end
162
+
163
+ def compact_instance_block(name)
164
+ lines = []
165
+ lines << "# @!method self.#{name}"
166
+ lines << "# @!macro #{MACRO_FINDER} #{name}"
167
+ lines << "# @!method #{name}?"
168
+ lines << "# @!macro #{MACRO_PREDICATE} #{name}"
169
+ klass.support_table_attribute_helpers.each do |attribute_name|
170
+ return_type = attribute_yard_return_type(name, attribute_name)
171
+ lines << "# @!method self.#{name}_#{attribute_name}"
172
+ lines << "# @!macro #{MACRO_ATTRIBUTE} #{name} #{attribute_name} #{return_type}"
173
+ end
174
+ lines.join("\n")
175
+ end
176
+
177
+ def attribute_yard_return_type(name, attribute_name)
178
+ TypeInference.yard_type(TypeInference.value_type(klass, "#{name}_#{attribute_name}"))
179
+ end
89
180
  end
90
181
  end
91
182
  end
@@ -2,8 +2,10 @@
2
2
 
3
3
  module SupportTableData
4
4
  module Documentation
5
+ autoload :TypeInference, File.expand_path("documentation/type_inference", __dir__)
6
+ autoload :SourceFile, File.expand_path("documentation/source_file", __dir__)
7
+ autoload :YardDoc, File.expand_path("documentation/yard_doc", __dir__)
8
+ autoload :RbsDoc, File.expand_path("documentation/rbs_doc", __dir__)
9
+ autoload :RbsFile, File.expand_path("documentation/rbs_file", __dir__)
5
10
  end
6
11
  end
7
-
8
- require_relative "documentation/source_file"
9
- require_relative "documentation/yard_doc"
@@ -23,7 +23,8 @@ module SupportTableData
23
23
  # @param file_path [String, Pathname, nil] Optional file path to filter by.
24
24
  # @return [Array<SupportTableData::Documentation::SourceFile>]
25
25
  def support_table_sources(file_path = nil)
26
- require_relative file_path if file_path
26
+ file_path = Pathname.new(file_path) if file_path.is_a?(String)
27
+ require file_path.expand_path if file_path
27
28
 
28
29
  sources = []
29
30
 
@@ -51,6 +52,16 @@ module SupportTableData
51
52
  []
52
53
  end
53
54
 
55
+ # Return RBS file handlers for all support table models.
56
+ #
57
+ # @param file_path [String, Pathname, nil] Optional file path to filter by.
58
+ # @return [Array<SupportTableData::Documentation::RbsFile>]
59
+ def support_table_rbs_files(file_path = nil)
60
+ support_table_sources(file_path).map do |source|
61
+ Documentation::RbsFile.new(source.klass, source.path)
62
+ end
63
+ end
64
+
54
65
  def model_file_path(klass)
55
66
  file_path = "#{klass.name.underscore}.rb"
56
67
  model_path = nil
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SupportTableData
4
+ module Tasks
5
+ autoload :Utils, File.expand_path("tasks/utils", __dir__)
6
+ end
7
+ end
@@ -8,7 +8,14 @@
8
8
  module SupportTableData
9
9
  extend ActiveSupport::Concern
10
10
 
11
+ autoload :ValidationError, File.expand_path("support_table_data/validation_error", __dir__)
12
+ autoload :Documentation, File.expand_path("support_table_data/documentation", __dir__)
13
+ autoload :Tasks, File.expand_path("support_table_data/tasks", __dir__)
14
+
15
+ YARD_DOC_OPTIONS = [:full, :compact, :none].freeze
16
+
11
17
  @data_directory = nil
18
+ @rbs_signatures_path = nil
12
19
 
13
20
  included do
14
21
  # Internal variables used for memoization.
@@ -31,6 +38,15 @@ module SupportTableData
31
38
  # value set by SupportTableData.data_directory. This is only used if relative paths are passed
32
39
  # in to add_support_table_data.
33
40
  class_attribute :support_table_data_directory, instance_accessor: false
41
+
42
+ # Private class attribute backing `support_table_yard_docs`. Use the public
43
+ # accessor to read/write.
44
+ # @private
45
+ class_attribute :_support_table_yard_docs, instance_accessor: false, default: :full
46
+ class << self
47
+ private :_support_table_yard_docs=
48
+ private :_support_table_yard_docs
49
+ end
34
50
  end
35
51
 
36
52
  class_methods do
@@ -48,12 +64,39 @@ module SupportTableData
48
64
  _support_table_key_attribute || "id"
49
65
  end
50
66
 
67
+ # Get the YARD documentation mode for this model. One of:
68
+ #
69
+ # * `:full` - emit a verbose comment block per generated method (default)
70
+ # * `:compact` - emit shared @!macro definitions plus a short
71
+ # @!method/@!macro pair per generated method
72
+ # * `:none` - generate no YARD docs for this model; the rake task will
73
+ # strip any existing generated YARD docs
74
+ #
75
+ # @return [Symbol]
76
+ def support_table_yard_docs
77
+ _support_table_yard_docs
78
+ end
79
+
80
+ # Set the YARD documentation mode for this model. See `support_table_yard_docs`
81
+ # for the supported values.
82
+ #
83
+ # @param value [Symbol]
84
+ # @return [void]
85
+ def support_table_yard_docs=(value)
86
+ unless SupportTableData::YARD_DOC_OPTIONS.include?(value)
87
+ raise ArgumentError, "support_table_yard_docs must be one of #{SupportTableData::YARD_DOC_OPTIONS.inspect} (got #{value.inspect})"
88
+ end
89
+ self._support_table_yard_docs = value
90
+ end
91
+
51
92
  # Synchronize the rows in the table with the values defined in the data files added with
52
- # `add_support_table_data`. Note that rows will not be deleted if they are no longer in
53
- # the data files.
93
+ # `add_support_table_data`. By default, rows that are no longer present in the data files
94
+ # will not be deleted unless `delete_missing` is enabled.
54
95
  #
96
+ # @param delete_missing [Boolean] If true, then any records in the database that are not in the data
97
+ # files will be deleted. Use with caution.
55
98
  # @return [Array<Hash>] List of saved changes for each record that was created or modified.
56
- def sync_table_data!
99
+ def sync_table_data!(delete_missing: false)
57
100
  return unless table_exists?
58
101
 
59
102
  canonical_data = support_table_data.each_with_object({}) do |attributes, hash|
@@ -64,6 +107,8 @@ module SupportTableData
64
107
 
65
108
  begin
66
109
  ActiveSupport::Notifications.instrument("support_table_data.sync", class: self) do
110
+ synced_ids = []
111
+
67
112
  transaction do
68
113
  records.each do |record|
69
114
  key = record[support_table_key_attribute].to_s
@@ -75,6 +120,8 @@ module SupportTableData
75
120
  changes << record.changes
76
121
  record.save!
77
122
  end
123
+
124
+ synced_ids << record.id if attributes
78
125
  end
79
126
 
80
127
  canonical_data.each_value do |attributes|
@@ -86,6 +133,11 @@ module SupportTableData
86
133
  end
87
134
  changes << record.changes
88
135
  record.save!
136
+ synced_ids << record.id
137
+ end
138
+
139
+ if delete_missing
140
+ where.not(primary_key => synced_ids).destroy_all
89
141
  end
90
142
  end
91
143
  end
@@ -373,6 +425,14 @@ module SupportTableData
373
425
  @data_directory = value&.to_s
374
426
  end
375
427
 
428
+ # Override the directory under which generated RBS signature files are
429
+ # written. When nil (the default) signatures go to
430
+ # `<project_root>/sig/<model_path>.rbs`, where the project root is the
431
+ # nearest ancestor directory containing a Gemfile or .git directory.
432
+ #
433
+ # @return [String, Pathname, nil]
434
+ attr_accessor :rbs_signatures_path
435
+
376
436
  # Sync all support table classes. Classes must already be loaded in order to be synced.
377
437
  #
378
438
  # You can pass in a list of classes that you want to ensure are synced. This feature
@@ -382,11 +442,13 @@ module SupportTableData
382
442
  # when the test suite is initializing.
383
443
  #
384
444
  # @param extra_classes [Class] List of classes to force into the detected list of classes to sync.
445
+ # @param delete_missing [Boolean] If true, then any records in the database that are not in the data
446
+ # files will be deleted from each table. Use with caution.
385
447
  # @return [Hash<Class, Array<Hash>] Hash of classes synced with a list of saved changes.
386
- def sync_all!(*extra_classes)
448
+ def sync_all!(*extra_classes, delete_missing: false)
387
449
  changes = {}
388
450
  support_table_classes(*extra_classes).each do |klass|
389
- changes[klass] = klass.sync_table_data!
451
+ changes[klass] = klass.sync_table_data!(delete_missing: delete_missing)
390
452
  end
391
453
  changes
392
454
  end
@@ -483,8 +545,6 @@ module SupportTableData
483
545
  end
484
546
  end
485
547
 
486
- require_relative "support_table_data/validation_error"
487
-
488
548
  if defined?(Rails::Railtie)
489
549
  require_relative "support_table_data/railtie"
490
550
  end
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :support_table_data do
4
- desc "Syncronize data for all models that include SupportTableData."
4
+ desc "Synchronize data for all models that include SupportTableData."
5
5
  task sync: :environment do
6
- require_relative "utils"
7
-
8
6
  SupportTableData::Tasks::Utils.eager_load!
9
7
 
10
8
  logger_callback = lambda do |name, started, finished, unique_id, payload|
@@ -23,14 +21,12 @@ namespace :support_table_data do
23
21
  end
24
22
  end
25
23
 
24
+ desc "Adds YARD documentation comments to all support table models to document the named instance methods."
26
25
  task yard_docs: "yard_docs:add"
27
26
 
28
27
  namespace :yard_docs do
29
28
  desc "Adds YARD documentation comments to models to document the named instance methods. Optional arg: file_path"
30
29
  task :add, [:file_path] => :environment do |_task, args|
31
- require_relative "../support_table_data/documentation"
32
- require_relative "utils"
33
-
34
30
  SupportTableData::Tasks::Utils.eager_load!
35
31
  SupportTableData::Tasks::Utils.support_table_sources(args[:file_path]).each do |source_file|
36
32
  next if source_file.yard_docs_up_to_date?
@@ -42,9 +38,6 @@ namespace :support_table_data do
42
38
 
43
39
  desc "Removes YARD documentation comments added by support_table_data from models. Optional arg: file_path"
44
40
  task :remove, [:file_path] => :environment do |_task, args|
45
- require_relative "../support_table_data/documentation"
46
- require_relative "utils"
47
-
48
41
  SupportTableData::Tasks::Utils.eager_load!
49
42
  SupportTableData::Tasks::Utils.support_table_sources(args[:file_path]).each do |source_file|
50
43
  next unless source_file.has_yard_docs?
@@ -56,9 +49,6 @@ namespace :support_table_data do
56
49
 
57
50
  desc "Verify that support table models have up to date YARD docs for named instance methods. Optional arg: file_path"
58
51
  task :verify, [:file_path] => :environment do |_task, args|
59
- require_relative "../support_table_data/documentation"
60
- require_relative "utils"
61
-
62
52
  SupportTableData::Tasks::Utils.eager_load!
63
53
 
64
54
  all_up_to_date = true
@@ -80,4 +70,53 @@ namespace :support_table_data do
80
70
  end
81
71
  end
82
72
  end
73
+
74
+ desc "Generates RBS signature files for named instance methods in all support table models."
75
+ task rbs: "rbs:add"
76
+
77
+ namespace :rbs do
78
+ desc "Generates RBS signature files for named instance methods. Optional arg: file_path"
79
+ task :add, [:file_path] => :environment do |_task, args|
80
+ SupportTableData::Tasks::Utils.eager_load!
81
+ SupportTableData::Tasks::Utils.support_table_rbs_files(args[:file_path]).each do |rbs_file|
82
+ next if rbs_file.up_to_date?
83
+
84
+ rbs_file.write!
85
+ puts "Wrote RBS signatures for #{rbs_file.klass.name} to #{rbs_file.path}."
86
+ end
87
+ end
88
+
89
+ desc "Removes generated RBS signature files. Optional arg: file_path"
90
+ task :remove, [:file_path] => :environment do |_task, args|
91
+ SupportTableData::Tasks::Utils.eager_load!
92
+ SupportTableData::Tasks::Utils.support_table_rbs_files(args[:file_path]).each do |rbs_file|
93
+ next unless rbs_file.remove!
94
+
95
+ puts "Removed RBS signatures for #{rbs_file.klass.name} (#{rbs_file.path})."
96
+ end
97
+ end
98
+
99
+ desc "Verify that generated RBS signature files are up to date. Optional arg: file_path"
100
+ task :verify, [:file_path] => :environment do |_task, args|
101
+ SupportTableData::Tasks::Utils.eager_load!
102
+
103
+ all_up_to_date = true
104
+ SupportTableData::Tasks::Utils.support_table_rbs_files(args[:file_path]).each do |rbs_file|
105
+ unless rbs_file.up_to_date?
106
+ puts "RBS signatures are not up to date for #{rbs_file.klass.name} (#{rbs_file.path})."
107
+ all_up_to_date = false
108
+ end
109
+ end
110
+
111
+ if all_up_to_date
112
+ if args[:file_path]
113
+ puts "RBS signatures are up to date for #{args[:file_path]}."
114
+ else
115
+ puts "All support table models have up to date RBS signatures."
116
+ end
117
+ else
118
+ raise "Run bundle exec rake support_table_data:rbs to update the signatures."
119
+ end
120
+ end
121
+ end
83
122
  end
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  bin/
28
28
  gemfiles/
29
29
  spec/
30
+ test_app/
30
31
  ]
31
32
  spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
32
33
  `git ls-files -z`.split("\x0").reject { |f| ignore_files.any? { |path| f.start_with?(path) } }
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.2
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
@@ -50,36 +50,17 @@ files:
50
50
  - VERSION
51
51
  - lib/support_table_data.rb
52
52
  - lib/support_table_data/documentation.rb
53
+ - lib/support_table_data/documentation/rbs_doc.rb
54
+ - lib/support_table_data/documentation/rbs_file.rb
53
55
  - lib/support_table_data/documentation/source_file.rb
56
+ - lib/support_table_data/documentation/type_inference.rb
54
57
  - lib/support_table_data/documentation/yard_doc.rb
55
58
  - lib/support_table_data/railtie.rb
59
+ - lib/support_table_data/tasks.rb
60
+ - lib/support_table_data/tasks/utils.rb
56
61
  - lib/support_table_data/validation_error.rb
57
62
  - lib/tasks/support_table_data.rake
58
- - lib/tasks/utils.rb
59
63
  - support_table_data.gemspec
60
- - test_app/.gitignore
61
- - test_app/Gemfile
62
- - test_app/Rakefile
63
- - test_app/app/models/application_record.rb
64
- - test_app/app/models/secondary_application_record.rb
65
- - test_app/app/models/status.rb
66
- - test_app/app/models/thing.rb
67
- - test_app/bin/rails
68
- - test_app/config.ru
69
- - test_app/config/application.rb
70
- - test_app/config/boot.rb
71
- - test_app/config/database.yml
72
- - test_app/config/environment.rb
73
- - test_app/config/environments/development.rb
74
- - test_app/config/environments/test.rb
75
- - test_app/db/migrate/20260103060951_create_status.rb
76
- - test_app/db/schema.rb
77
- - test_app/db/secondary_migrate/20260104000001_create_things.rb
78
- - test_app/db/secondary_schema.rb
79
- - test_app/db/support_tables/statuses.yml
80
- - test_app/db/support_tables/things.yml
81
- - test_app/lib/tasks/database.rake
82
- - test_app/log/.keep
83
64
  homepage: https://github.com/bdurand/support_table_data
84
65
  licenses:
85
66
  - MIT
@@ -101,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
82
  - !ruby/object:Gem::Version
102
83
  version: '0'
103
84
  requirements: []
104
- rubygems_version: 4.0.3
85
+ rubygems_version: 3.6.9
105
86
  specification_version: 4
106
87
  summary: Extension for ActiveRecord models to manage synchronizing data in support/lookup
107
88
  tables across environments. Also provides the ability to directly reference and
data/test_app/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- log/*.log
2
- tmp/
3
- doc/
4
- db/*.sqlite3
data/test_app/Gemfile DELETED
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "rails", "~> 8.1.1"
4
-
5
- gem "sqlite3", "~> 2.9.0"
6
-
7
- gem "support_table_data", path: ".."
data/test_app/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- # Add your own tasks in files placed in lib/tasks ending in .rake,
2
- # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
-
4
- require_relative "config/application"
5
-
6
- Rails.application.load_tasks
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class ApplicationRecord < ActiveRecord::Base
4
- self.abstract_class = true
5
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SecondaryApplicationRecord < ApplicationRecord
4
- self.abstract_class = true
5
-
6
- connects_to database: {writing: :secondary, reading: :secondary}
7
- end
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Status < ApplicationRecord
4
- include SupportTableData
5
-
6
- self.support_table_key_attribute = :code
7
- add_support_table_data "statuses.yml"
8
- named_instance_attribute_helpers :name
9
-
10
- validates :code, presence: true, uniqueness: true
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
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Thing < SecondaryApplicationRecord
4
- include SupportTableData
5
-
6
- self.support_table_key_attribute = :id
7
- add_support_table_data "things.yml"
8
-
9
- validates :name, presence: true, uniqueness: true
10
- end
data/test_app/bin/rails DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path("../config/application", __dir__)
3
- require_relative "../config/boot"
4
- require "rails/commands"
@@ -1,42 +0,0 @@
1
- require_relative "boot"
2
-
3
- require "rails"
4
- # Pick the frameworks you want:
5
- # require "active_model/railtie"
6
- # require "active_job/railtie"
7
- require "active_record/railtie"
8
- # require "active_storage/engine"
9
- # require "action_controller/railtie"
10
- # require "action_mailer/railtie"
11
- # require "action_mailbox/engine"
12
- # require "action_text/engine"
13
- # require "action_view/railtie"
14
- # require "action_cable/engine"
15
- # require "rails/test_unit/railtie"
16
-
17
- # Require the gems listed in Gemfile, including any gems
18
- # you've limited to :test, :development, or :production.
19
- Bundler.require(*Rails.groups)
20
-
21
- module TestApp
22
- class Application < Rails::Application
23
- # Initialize configuration defaults for originally generated Rails version.
24
- config.load_defaults 8.1
25
-
26
- # Please, add to the `ignore` list any other `lib` subdirectories that do
27
- # not contain `.rb` files, or that should not be reloaded or eager loaded.
28
- # Common ones are `templates`, `generators`, or `middleware`, for example.
29
- config.autoload_lib(ignore: %w[assets tasks])
30
-
31
- # Configuration for the application, engines, and railties goes here.
32
- #
33
- # These settings can be overridden in specific environments using the files
34
- # in config/environments, which are processed later.
35
- #
36
- # config.time_zone = "Central Time (US & Canada)"
37
- config.eager_load_paths << Rails.root.join("app", "configurations")
38
-
39
- # Don't generate system test files.
40
- config.generators.system_tests = nil
41
- end
42
- end
@@ -1,3 +0,0 @@
1
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
2
-
3
- require "bundler/setup" # Set up gems listed in the Gemfile.
@@ -1,17 +0,0 @@
1
- development:
2
- primary:
3
- adapter: sqlite3
4
- database: db/development.sqlite3
5
- secondary:
6
- adapter: sqlite3
7
- database: db/secondary_development.sqlite3
8
- migrations_paths: db/secondary_migrate
9
-
10
- test:
11
- primary:
12
- adapter: sqlite3
13
- database: db/test.sqlite3
14
- secondary:
15
- adapter: sqlite3
16
- database: db/secondary_test.sqlite3
17
- migrations_paths: db/secondary_migrate
@@ -1,5 +0,0 @@
1
- # Load the Rails application.
2
- require_relative "application"
3
-
4
- # Initialize the Rails application.
5
- Rails.application.initialize!
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Rails.application.configure do
4
- # Settings specified here will take precedence over those in config/application.rb.
5
-
6
- # Make code changes take effect immediately without server restart.
7
- config.enable_reloading = true
8
-
9
- # Do not eager load code on boot.
10
- config.eager_load = false
11
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Rails.application.configure do
4
- # Settings specified here will take precedence over those in config/application.rb.
5
-
6
- # Make code changes take effect immediately without server restart.
7
- config.enable_reloading = true
8
-
9
- # Do not eager load code on boot.
10
- config.eager_load = false
11
- end
data/test_app/config.ru DELETED
@@ -1,6 +0,0 @@
1
- # This file is used by Rack-based servers to start the application.
2
-
3
- require_relative "config/environment"
4
-
5
- # run Rails.application
6
- # Rails.application.load_server
@@ -1,8 +0,0 @@
1
- class CreateStatus < ActiveRecord::Migration[8.1]
2
- def change
3
- create_table :statuses do |t|
4
- t.string :code, null: false, index: {unique: true}
5
- t.string :name, null: false, index: {unique: true}
6
- end
7
- end
8
- end
@@ -1,20 +0,0 @@
1
- # This file is auto-generated from the current state of the database. Instead
2
- # of editing this file, please use the migrations feature of Active Record to
3
- # incrementally modify your database, and then regenerate this schema definition.
4
- #
5
- # This file is the source Rails uses to define your schema when running `bin/rails
6
- # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
- # be faster and is potentially less error prone than running all of your
8
- # migrations from scratch. Old migrations may fail to apply correctly if those
9
- # migrations use external dependencies or application code.
10
- #
11
- # It's strongly recommended that you check this file into your version control system.
12
-
13
- ActiveRecord::Schema[8.1].define(version: 2026_01_03_060951) do
14
- create_table "statuses", force: :cascade do |t|
15
- t.string "code", null: false
16
- t.string "name", null: false
17
- t.index ["code"], name: "index_statuses_on_code", unique: true
18
- t.index ["name"], name: "index_statuses_on_name", unique: true
19
- end
20
- end
@@ -1,7 +0,0 @@
1
- class CreateThings < ActiveRecord::Migration[8.1]
2
- def change
3
- create_table :things do |t|
4
- t.string :name, null: false, index: {unique: true}
5
- end
6
- end
7
- end
@@ -1,25 +0,0 @@
1
- # This file is auto-generated from the current state of the database. Instead
2
- # of editing this file, please use the migrations feature of Active Record to
3
- # incrementally modify your database, and then regenerate this schema definition.
4
- #
5
- # This file is the source Rails uses to define your schema when running `bin/rails
6
- # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
- # be faster and is potentially less error prone than running all of your
8
- # migrations from scratch. Old migrations may fail to apply correctly if those
9
- # migrations use external dependencies or application code.
10
- #
11
- # It's strongly recommended that you check this file into your version control system.
12
-
13
- ActiveRecord::Schema[8.1].define(version: 2026_01_04_000001) do
14
- create_table "statuses", force: :cascade do |t|
15
- t.string "code", null: false
16
- t.string "name", null: false
17
- t.index ["code"], name: "index_statuses_on_code", unique: true
18
- t.index ["name"], name: "index_statuses_on_name", unique: true
19
- end
20
-
21
- create_table "things", force: :cascade do |t|
22
- t.string "name", null: false
23
- t.index ["name"], name: "index_things_on_name", unique: true
24
- end
25
- end
@@ -1,19 +0,0 @@
1
- pending:
2
- code: pending
3
- name: Pending
4
-
5
- active:
6
- code: active
7
- name: Active
8
-
9
- completed:
10
- code: completed
11
- name: Completed
12
-
13
- canceled:
14
- code: canceled
15
- name: Canceled
16
-
17
- failed:
18
- code: failed
19
- name: Failed
@@ -1,5 +0,0 @@
1
- - id: 1
2
- name: Thing One
3
-
4
- - id: 2
5
- name: Thing Two
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if Rake::Task.task_defined?("db:migrate")
4
- Rake::Task["db:migrate"].enhance do
5
- # The main database connection may have artifacts from the migration, so re-establish it
6
- # to get a clean connection before syncing support table data.
7
- ActiveRecord::Base.establish_connection
8
-
9
- Rake::Task["support_table_data:sync"].invoke
10
- end
11
- end
data/test_app/log/.keep DELETED
File without changes