real_data_tests 0.3.18 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +24 -1
- data/lib/real_data_tests/configuration.rb +9 -0
- data/lib/real_data_tests/record_collector.rb +43 -5
- data/lib/real_data_tests/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f21f225cf114a1a334e786333cb7a5dcb04a261636590c890b85d3443c9659d3
|
|
4
|
+
data.tar.gz: 024b43b99b9b6880730c1a02d799c83fcec5be3a949fd38c5c25a2bf2fdf7d71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eceeaed220dae3072480315cb9c2623540231f3c7aca876727681f6511112d95e7a4b0f894800c17db5f79b939410ebac8288adfd88911c1c446e52005e0a3e4
|
|
7
|
+
data.tar.gz: dd75263ec204aaef5d544ae7d257b0428f59273046158de7f31d0d54f053ae1065e7a6272ef6335ed5db5eaea217a204ca1d567bd1bded5d957d9e66dde84aba
|
data/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
## [0.4.0] - 2026-04-06
|
|
2
|
+
### Added
|
|
3
|
+
- **Bypass Default Scope Support**:
|
|
4
|
+
- New `bypass_default_scope` configuration option for presets
|
|
5
|
+
- When enabled, unscopes `default_scope` from all defined models during record collection
|
|
6
|
+
- Ensures soft-deleted and other normally-hidden records are captured, preventing orphaned foreign key references in fixtures
|
|
7
|
+
|
|
1
8
|
## [0.3.18] - 2025-02-05
|
|
2
9
|
### Fixed
|
|
3
10
|
- Fixed cross-model circular dependency handling in PgDumpGenerator
|
|
4
11
|
- The `prevent_circular_dependency` method previously only worked for self-referential associations (e.g., `ServiceRate → ServiceRate`) due to a guard clause (`assoc.klass == model`) in `build_dependency_graph`
|
|
5
12
|
- Removed the self-referential constraint so `prevent_circular_dependency` now correctly breaks cycles between different models (e.g., `Organization → User → Organization`)
|
|
6
|
-
- This bug was latent and became visible in Ruby 3.2.10 due to changes in hash/set iteration ordering that altered association traversal order
|
|
7
13
|
|
|
8
14
|
## [0.3.5 - 0.3.17] - 2025-01-14
|
|
9
15
|
### Fixed
|
data/README.md
CHANGED
|
@@ -329,6 +329,29 @@ RealDataTests.configure do |config|
|
|
|
329
329
|
end
|
|
330
330
|
```
|
|
331
331
|
|
|
332
|
+
### Bypassing Default Scopes
|
|
333
|
+
|
|
334
|
+
Rails models sometimes define a `default_scope` that excludes certain records, such as soft-deleted ones:
|
|
335
|
+
|
|
336
|
+
```ruby
|
|
337
|
+
class VisitNote < ApplicationRecord
|
|
338
|
+
default_scope { where(deleted_at: nil) }
|
|
339
|
+
end
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
By default, Real Data Tests respects these scopes, meaning soft-deleted records won't be included in your dumps. Since SQL fixtures should mirror what actually exists in the database, you can bypass default scopes to ensure all records are captured:
|
|
343
|
+
|
|
344
|
+
```ruby
|
|
345
|
+
RealDataTests.configure do |config|
|
|
346
|
+
config.preset :patient_data do |p|
|
|
347
|
+
p.bypass_default_scope
|
|
348
|
+
|
|
349
|
+
p.include_associations_for 'Patient', :visit_notes
|
|
350
|
+
p.include_associations_for 'VisitNote', :patient
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
```
|
|
354
|
+
|
|
332
355
|
### Best Practices for Association Control
|
|
333
356
|
|
|
334
357
|
1. **Start with Global Rules**: Define global association rules that apply to most models
|
|
@@ -455,4 +478,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
455
478
|
|
|
456
479
|
## Code of Conduct
|
|
457
480
|
|
|
458
|
-
Everyone interacting in the Real Data Tests project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/diasks2/real_data_tests/blob/main/CODE_OF_CONDUCT.md).
|
|
481
|
+
Everyone interacting in the Real Data Tests project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/diasks2/real_data_tests/blob/main/CODE_OF_CONDUCT.md).
|
|
@@ -74,10 +74,19 @@ module RealDataTests
|
|
|
74
74
|
@prevent_reciprocal_loading = {}
|
|
75
75
|
@anonymization_rules = {}
|
|
76
76
|
@prevented_reciprocals = Set.new
|
|
77
|
+
@bypass_default_scope = false
|
|
77
78
|
@max_depth = 10
|
|
78
79
|
@max_self_ref_depth = 2
|
|
79
80
|
end
|
|
80
81
|
|
|
82
|
+
def bypass_default_scope(value = true)
|
|
83
|
+
@bypass_default_scope = value
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def bypass_default_scope?
|
|
87
|
+
@bypass_default_scope
|
|
88
|
+
end
|
|
89
|
+
|
|
81
90
|
def prevent_circular_dependency(klass, association_name)
|
|
82
91
|
key = if klass.is_a?(String)
|
|
83
92
|
"#{klass}:#{association_name}"
|
|
@@ -61,11 +61,11 @@ module RealDataTests
|
|
|
61
61
|
record.class.reflect_on_all_associations(:belongs_to).each do |assoc|
|
|
62
62
|
next unless assoc.polymorphic?
|
|
63
63
|
|
|
64
|
-
type = record.public_send(
|
|
64
|
+
type = record.public_send(assoc.foreign_type)
|
|
65
65
|
@collection_stats[record.class.name][:polymorphic_types][assoc.name.to_sym] ||= Set.new
|
|
66
66
|
|
|
67
67
|
begin
|
|
68
|
-
associated_record = record
|
|
68
|
+
associated_record = load_association(record, assoc)
|
|
69
69
|
if associated_record
|
|
70
70
|
puts " Adding polymorphic type '#{type}' for #{assoc.name}"
|
|
71
71
|
@collection_stats[record.class.name][:polymorphic_types][assoc.name.to_sym] << associated_record.class.name
|
|
@@ -215,9 +215,9 @@ module RealDataTests
|
|
|
215
215
|
def fetch_related_records(record, association)
|
|
216
216
|
case association.macro
|
|
217
217
|
when :belongs_to, :has_one
|
|
218
|
-
Array(record
|
|
218
|
+
Array(load_association(record, association)).compact
|
|
219
219
|
when :has_many, :has_and_belongs_to_many
|
|
220
|
-
relation = record
|
|
220
|
+
relation = load_association(record, association)
|
|
221
221
|
|
|
222
222
|
if limit = RealDataTests.configuration.current_preset.get_association_limit(record.class, association.name)
|
|
223
223
|
puts " Applying configured limit of #{limit} records for #{record.class.name}.#{association.name}"
|
|
@@ -230,6 +230,44 @@ module RealDataTests
|
|
|
230
230
|
end
|
|
231
231
|
end
|
|
232
232
|
|
|
233
|
+
def load_association(record, association)
|
|
234
|
+
if RealDataTests.configuration.current_preset.bypass_default_scope?
|
|
235
|
+
load_association_unscoped(record, association)
|
|
236
|
+
else
|
|
237
|
+
record.public_send(association.name)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def load_association_unscoped(record, association)
|
|
242
|
+
if association.polymorphic?
|
|
243
|
+
type_value = record.public_send(association.foreign_type)
|
|
244
|
+
id_value = record.public_send(association.foreign_key)
|
|
245
|
+
return nil if type_value.blank? || id_value.blank?
|
|
246
|
+
klass = type_value.constantize
|
|
247
|
+
klass.unscoped.find_by(klass.primary_key => id_value)
|
|
248
|
+
else
|
|
249
|
+
case association.macro
|
|
250
|
+
when :belongs_to, :has_one
|
|
251
|
+
# If the association was loaded at any point before the collector runs, reset it so that the
|
|
252
|
+
# default scopes are properly bypassed.
|
|
253
|
+
record.association(association.name).reset
|
|
254
|
+
without_default_scope(association) { record.public_send(association.name) }
|
|
255
|
+
when :has_many, :has_and_belongs_to_many
|
|
256
|
+
without_default_scope(association) { record.public_send(association.name).to_a }
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def without_default_scope(association)
|
|
262
|
+
if association.through_reflection?
|
|
263
|
+
association.through_reflection.klass.unscoped do
|
|
264
|
+
association.klass.unscoped { yield }
|
|
265
|
+
end
|
|
266
|
+
else
|
|
267
|
+
association.klass.unscoped { yield }
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
233
271
|
def print_collection_stats
|
|
234
272
|
puts "\n=== Collection Statistics ==="
|
|
235
273
|
@collection_stats.each do |model, stats|
|
|
@@ -254,4 +292,4 @@ module RealDataTests
|
|
|
254
292
|
puts "==============================\n"
|
|
255
293
|
end
|
|
256
294
|
end
|
|
257
|
-
end
|
|
295
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: real_data_tests
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kevin Dias
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|