support_table_data 1.2.4 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25c555ca2a0e07c825f2b13c70224cf4e4ae27e489bad54e4e9f5983fa26df8a
4
- data.tar.gz: b033e09b4eac22c923dc489d8d9762ffad9fdfec65f8fe25f20d13bd76339a48
3
+ metadata.gz: 246d91c74bc3b4a5afc75899786785139dc4b9bde91f0af778af63d1f374306b
4
+ data.tar.gz: c7290495c52166a9068806ffce68fbb6f161cdebf87546e6eae4a9b9c97deacc
5
5
  SHA512:
6
- metadata.gz: ad12a5e0be457211552148035f0102b484ac27d17868f7a41d471b95b65b2e933e95e6179068f9fd6f4e09987e005bcf22bdef9748dbb8e04e566cc30053f542
7
- data.tar.gz: a891b014ff3d7b92d26375223e61cf0f8419f05bbb0f55b2a16d8602b634c36f9f8d3449e301bc1fd23a03defadb24150c64902ea0f5530914db8d62780279a5
6
+ metadata.gz: f32896080f819f65bfcc59e38801cb69a5a5f98ccc83e6218c587766c5b769aab034b606452909cf9e62a6ea82a23e79150bae42201b73c374489563ed3d1537
7
+ data.tar.gz: ea9af78e06f7439854e7444eab0f96a541a14b7c5918767a464eb56094f415c71b5349b4a2043d12ac1bdebff47d1b8ee485e329cd10112b6c11f11389cbe595
data/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ 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.3.1
8
+
9
+ ### Added
10
+
11
+ - Added support for autosave associations. Data in autosave associations will be persisted when the support table is synced if it was changed by the support table data.
12
+
13
+ ## 1.3.0
14
+
15
+ ### Added
16
+
17
+ - Added `support_table_dependency` method to explicitly define support table dependencies that cannot be inferred from model associations.
18
+
7
19
  ## 1.2.4
8
20
 
9
21
  ### Fixed
data/README.md CHANGED
@@ -57,6 +57,8 @@ You cannot update the value of the key attribute in a record in the data file. I
57
57
 
58
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.
59
59
 
60
+ **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
+
60
62
  ### Named Instances
61
63
 
62
64
  You can also automatically define helper methods to load instances and determine if they match specific values. This allows you to add more natural ways of referencing specific records.
@@ -212,7 +214,37 @@ Loading data is done inside a database transaction. No changes will be persisted
212
214
 
213
215
  You can synchronize the data in all models by calling `SupportTableData.sync_all!`. This method will discover all ActiveRecord models that include `SupportTableData` and synchronize each of them. (Note that there can be issues discovering all support table models in a Rails application if eager loading is turned off.) The discovery mechanism will try to detect unloaded classes by looking at the file names in the support table data directory so it's best to stick to standard Rails naming conventions for your data files.
214
216
 
215
- The load order for models will resolve any dependencies between models. So if one model has a `belongs_to` association with another model, then the belongs to model will be loaded first.
217
+ The load order for models will resolve any dependencies between models. So if one model has a `belongs_to` association with another model, then the belongs to model will be loaded first. You can also explicitly define dependencies with the `support_table_dependency` method. If you have a join table between support tables that creates a circular dependency, then you will need to define which model to load first.
218
+
219
+ ```ruby
220
+ class Widget < ApplicationRecord
221
+ include SupportTableData
222
+
223
+ add_support_table_data "widgets.yml"
224
+
225
+ has_many :thing_widgets
226
+ has_many :things, through: :thing_widgets
227
+ end
228
+
229
+ class Thing < ApplicationRecord
230
+ include SupportTableData
231
+
232
+ add_support_table_data "things.yml"
233
+
234
+ has_many :thing_widgets
235
+ has_many :widgets, through: :thing_widgets, autosave: true
236
+
237
+ # The Thing model is responsible for loading the thing_widgets join table by means of the widget_names=
238
+ # setter method. We need to define the depdenency to ensure widgets are loaded first.
239
+ support_table_dependency "Widget"
240
+
241
+ def widget_names=(widget_names)
242
+ self.widgets = Widget.where(name: widget_names)
243
+ end
244
+ end
245
+ ```
246
+
247
+ 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.
216
248
 
217
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:
218
250
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.4
1
+ 1.3.1
@@ -15,6 +15,7 @@ module SupportTableData
15
15
  @support_table_attribute_helpers = {}
16
16
  @support_table_instance_names = {}
17
17
  @support_table_instance_keys = nil
18
+ @support_table_dependencies = []
18
19
 
19
20
  # Define the attribute used as the key of the hash in the data files.
20
21
  # This should be a value that never changes. By default the key attribute will be the id.
@@ -48,7 +49,7 @@ module SupportTableData
48
49
  attributes&.each do |name, value|
49
50
  record.send(:"#{name}=", value) if record.respond_to?(:"#{name}=", true)
50
51
  end
51
- if record.changed?
52
+ if support_table_record_changed?(record)
52
53
  changes << record.changes
53
54
  record.save!
54
55
  end
@@ -205,6 +206,20 @@ module SupportTableData
205
206
  @protected_keys.include?(instance[key_attribute].to_s)
206
207
  end
207
208
 
209
+ # Explicitly define other support tables that this model depends on. A support table depends
210
+ # on another support table it needs to reference data on that table when loading its own data.
211
+ # Normally this is handled automatically by looking at the belongs_to associations on the model.
212
+ # In some cases, though, you may need to explicitly define the relationship. For instance, if
213
+ # there's a join table between two associations with the data poplulated from one support table's
214
+ # data file by referencing values maintained by the other support table. In this case,
215
+ # you need to define the dependency so that the tables are loaded in the correct order.
216
+ #
217
+ # @param class_names [String] List of class names that this support table depends on.
218
+ # @return [void]
219
+ def support_table_dependency(*class_names)
220
+ @support_table_dependencies += class_names.flatten.collect(&:to_s)
221
+ end
222
+
208
223
  private
209
224
 
210
225
  def define_support_table_named_instances
@@ -308,6 +323,20 @@ module SupportTableData
308
323
 
309
324
  data
310
325
  end
326
+
327
+ def support_table_record_changed?(record, seen = Set.new)
328
+ return true if record.changed?
329
+
330
+ seen << self
331
+ record.class.reflect_on_all_associations.detect do |reflection|
332
+ next false if reflection.belongs_to?
333
+ next false unless reflection.options[:autosave]
334
+
335
+ record.association(reflection.name).target.any? do |child|
336
+ support_table_record_changed?(child, seen) unless seen.include?(child)
337
+ end
338
+ end
339
+ end
311
340
  end
312
341
 
313
342
  class << self
@@ -405,13 +434,17 @@ module SupportTableData
405
434
  #
406
435
  # @return [Array<Class>]
407
436
  def support_table_dependencies(klass)
408
- dependencies = []
437
+ dependencies = klass.instance_variable_get(:@support_table_dependencies).collect(&:constantize)
409
438
 
410
439
  klass.reflections.values.each do |reflection|
411
440
  next if reflection.polymorphic?
412
441
  next unless reflection.klass.include?(SupportTableData)
413
442
  next if reflection.klass <= klass
414
443
  next unless reflection.belongs_to? || reflection.through_reflection?
444
+ next if dependencies.include?(reflection.klass)
445
+
446
+ explicit_dependencies = reflection.klass.instance_variable_get(:@support_table_dependencies)
447
+ next if explicit_dependencies&.include?(klass.name)
415
448
 
416
449
  dependencies << reflection.klass
417
450
  rescue => e
@@ -9,6 +9,12 @@ Gem::Specification.new do |spec|
9
9
  spec.homepage = "https://github.com/bdurand/support_table_data"
10
10
  spec.license = "MIT"
11
11
 
12
+ spec.metadata = {
13
+ "homepage_uri" => spec.homepage,
14
+ "source_code_uri" => spec.homepage,
15
+ "changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md"
16
+ }
17
+
12
18
  # Specify which files should be added to the gem when it is released.
13
19
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
14
20
  ignore_files = %w[
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: support_table_data
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-26 00:00:00.000000000 Z
11
+ date: 2025-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -56,7 +56,10 @@ files:
56
56
  homepage: https://github.com/bdurand/support_table_data
57
57
  licenses:
58
58
  - MIT
59
- metadata: {}
59
+ metadata:
60
+ homepage_uri: https://github.com/bdurand/support_table_data
61
+ source_code_uri: https://github.com/bdurand/support_table_data
62
+ changelog_uri: https://github.com/bdurand/support_table_data/blob/master/CHANGELOG.md
60
63
  post_install_message:
61
64
  rdoc_options: []
62
65
  require_paths: