fixture_seed 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +17 -0
- data/lib/fixture_seed/loader.rb +85 -0
- data/lib/fixture_seed/railtie.rb +8 -13
- data/lib/fixture_seed/version.rb +1 -1
- data/lib/fixture_seed.rb +3 -95
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74ef9a7ff52401cea08e20f1f6610eb509d339b8aabb7ae249a231f1818661e5
|
4
|
+
data.tar.gz: 3a7f4bbf8ea02c63979e01893dd7f03635fc164e046ec87035eb27b6525a9f80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88e226a51a806e9cf69f4e44067f8c892c5b48c80d700e86fc4bf371417de570f5221d4fbe6cea2f3010a4b58df2474cfc5fafd507dc15b93ac29b0b4abd8c66
|
7
|
+
data.tar.gz: dd409f1d8f5974b4bf1d169879dbdc078f065278d7313808bba22325543015b9d606b0ca660182465bd6ac9d2389f2a3fd9c875541f810623ff2f1b6bd26923d
|
data/README.md
CHANGED
@@ -52,6 +52,23 @@ user2:
|
|
52
52
|
|
53
53
|
The labels (e.g., `user1`, `user2`) should follow the pattern of the table name in singular form followed by a number.
|
54
54
|
|
55
|
+
#### ERB Support
|
56
|
+
|
57
|
+
For dynamic fixture generation, you can use ERB templates in your YAML files:
|
58
|
+
|
59
|
+
```erb
|
60
|
+
# users.yml
|
61
|
+
<% 10.times do |i| %>
|
62
|
+
user<%= i + 1 %>:
|
63
|
+
id: <%= i + 1 %>
|
64
|
+
name: "User <%= i + 1 %>"
|
65
|
+
email: "user<%= i + 1 %>@example.com"
|
66
|
+
created_at: <%= Time.current.to_s(:db) %>
|
67
|
+
<% end %>
|
68
|
+
```
|
69
|
+
|
70
|
+
ERB templates have access to the full Rails environment, allowing you to use helpers, constants, and other Ruby code to generate dynamic fixture data.
|
71
|
+
|
55
72
|
### Fixture Loading Order
|
56
73
|
|
57
74
|
#### Order-independent Loading
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/fixtures"
|
4
|
+
|
5
|
+
module FixtureSeed
|
6
|
+
class Loader
|
7
|
+
class << self
|
8
|
+
def load_fixtures(fixtures_path = nil)
|
9
|
+
fixtures_path ||= ENV["FIXTURES_PATH"] || "db/fixtures"
|
10
|
+
fixtures_dir = Rails.root.join(fixtures_path)
|
11
|
+
|
12
|
+
unless Dir.exist?(fixtures_dir)
|
13
|
+
logger = Rails.logger || Logger.new($stdout)
|
14
|
+
logger.info "[FixtureSeed] Fixtures directory not found: #{fixtures_path}"
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
18
|
+
logger = Rails.logger || Logger.new($stdout)
|
19
|
+
logger.info "[FixtureSeed] Loading fixtures from #{fixtures_path}"
|
20
|
+
|
21
|
+
ActiveRecord::Base.transaction do
|
22
|
+
with_foreign_keys_disabled do
|
23
|
+
load_fixture_files(fixtures_dir, logger)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
logger.info "[FixtureSeed] Finished loading fixtures"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def load_fixture_files(fixtures_dir, logger)
|
33
|
+
fixture_files = Dir.glob("#{fixtures_dir}/*.yml")
|
34
|
+
return if fixture_files.empty?
|
35
|
+
|
36
|
+
table_names = fixture_files.map { |f| File.basename(f, ".yml") }
|
37
|
+
logger.info "[FixtureSeed] Found tables: #{table_names.join(', ')}"
|
38
|
+
|
39
|
+
ordered_tables = dependency_ordered_tables(table_names)
|
40
|
+
|
41
|
+
ordered_tables.each do |table_name|
|
42
|
+
ActiveRecord::FixtureSet.create_fixtures(fixtures_dir.to_s, [table_name])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def dependency_ordered_tables(table_names)
|
47
|
+
ordered = []
|
48
|
+
ordered << "users" if table_names.include?("users")
|
49
|
+
ordered += (table_names - ["users"])
|
50
|
+
ordered
|
51
|
+
end
|
52
|
+
|
53
|
+
def with_foreign_keys_disabled
|
54
|
+
adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
|
55
|
+
|
56
|
+
disable_foreign_keys(adapter_name)
|
57
|
+
yield
|
58
|
+
ensure
|
59
|
+
enable_foreign_keys(adapter_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def disable_foreign_keys(adapter_name)
|
63
|
+
case adapter_name
|
64
|
+
when /postgresql/
|
65
|
+
ActiveRecord::Base.connection.execute("SET session_replication_role = replica;")
|
66
|
+
when /sqlite/
|
67
|
+
ActiveRecord::Base.connection.execute("PRAGMA foreign_keys = OFF;")
|
68
|
+
when /mysql/
|
69
|
+
ActiveRecord::Base.connection.execute("SET FOREIGN_KEY_CHECKS = 0;")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def enable_foreign_keys(adapter_name)
|
74
|
+
case adapter_name
|
75
|
+
when /postgresql/
|
76
|
+
ActiveRecord::Base.connection.execute("SET session_replication_role = DEFAULT;")
|
77
|
+
when /sqlite/
|
78
|
+
ActiveRecord::Base.connection.execute("PRAGMA foreign_keys = ON;")
|
79
|
+
when /mysql/
|
80
|
+
ActiveRecord::Base.connection.execute("SET FOREIGN_KEY_CHECKS = 1;")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/fixture_seed/railtie.rb
CHANGED
@@ -1,23 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "loader"
|
4
|
+
|
3
5
|
module FixtureSeed
|
4
6
|
class Railtie < Rails::Railtie
|
5
|
-
initializer "fixture_seed.initialize" do
|
6
|
-
Rails.logger.info "[FixtureSeed] Railtie initialized"
|
7
|
-
end
|
8
|
-
|
9
7
|
rake_tasks do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
Rails.logger.info "[FixtureSeed] Starting to load fixtures before db:seed"
|
15
|
-
FixtureSeed.load_fixtures
|
16
|
-
Rails.logger.info "[FixtureSeed] Finished loading fixtures"
|
8
|
+
namespace :fixture_seed do
|
9
|
+
desc "Load fixtures from specified directory"
|
10
|
+
task load_fixtures: :environment do
|
11
|
+
FixtureSeed::Loader.load_fixtures
|
17
12
|
end
|
18
|
-
else
|
19
|
-
Rails.logger.warn "[FixtureSeed] db:seed task not found, fixture loading enhancement not applied"
|
20
13
|
end
|
14
|
+
|
15
|
+
Rake::Task["db:seed"].enhance(["fixture_seed:load_fixtures"]) if Rake::Task.task_defined?("db:seed")
|
21
16
|
end
|
22
17
|
end
|
23
18
|
end
|
data/lib/fixture_seed/version.rb
CHANGED
data/lib/fixture_seed.rb
CHANGED
@@ -1,105 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "fixture_seed/version"
|
4
|
+
require_relative "fixture_seed/loader"
|
4
5
|
require_relative "fixture_seed/railtie" if defined?(Rails::Railtie)
|
5
6
|
|
6
7
|
module FixtureSeed
|
7
8
|
class Error < StandardError; end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
fixture_dir = Rails.root.join("db/fixtures").to_s
|
12
|
-
files_to_load = Dir.glob(File.join(fixture_dir, "*.yml")).sort
|
13
|
-
|
14
|
-
file_names = files_to_load.map { |f| File.basename(f) }.join(", ")
|
15
|
-
Rails.logger.info "[FixtureSeed] Found #{files_to_load.size} fixture files in #{fixture_dir}: #{file_names}"
|
16
|
-
|
17
|
-
# Load all fixtures with retry logic
|
18
|
-
unloaded_files = process_fixtures(fixture_dir, files_to_load)
|
19
|
-
|
20
|
-
# Report any fixtures that still failed
|
21
|
-
if unloaded_files.empty?
|
22
|
-
Rails.logger.info "[FixtureSeed] All fixtures loaded successfully."
|
23
|
-
else
|
24
|
-
message = "The following fixtures could not be loaded: #{unloaded_files.join(', ')}"
|
25
|
-
Rails.logger.warn "[FixtureSeed] #{message}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def process_fixtures(fixture_dir, files)
|
32
|
-
remaining_files = files.dup
|
33
|
-
previous_count = remaining_files.size + 1
|
34
|
-
|
35
|
-
# Continue until all fixtures are loaded or no progress is made
|
36
|
-
while !remaining_files.empty? && remaining_files.size < previous_count
|
37
|
-
previous_count = remaining_files.size
|
38
|
-
remaining_files = process_batch(fixture_dir, files, remaining_files)
|
39
|
-
end
|
40
|
-
|
41
|
-
remaining_files
|
42
|
-
end
|
43
|
-
|
44
|
-
def process_batch(fixture_dir, original_files, current_files)
|
45
|
-
still_failed = []
|
46
|
-
|
47
|
-
current_files.each do |file|
|
48
|
-
log_loading(file)
|
49
|
-
load_single_fixture(fixture_dir, file)
|
50
|
-
log_success(file, original_files, current_files)
|
51
|
-
rescue ActiveRecord::InvalidForeignKey, ActiveRecord::StatementInvalid => e
|
52
|
-
log_failure(file, e, original_files, current_files)
|
53
|
-
still_failed << file
|
54
|
-
end
|
55
|
-
|
56
|
-
still_failed
|
57
|
-
end
|
58
|
-
|
59
|
-
def load_single_fixture(_fixture_dir, file)
|
60
|
-
table_name = File.basename(file, ".yml")
|
61
|
-
yaml_data = YAML.load_file(file)
|
62
|
-
|
63
|
-
model_class = begin
|
64
|
-
table_name.classify.constantize
|
65
|
-
rescue StandardError
|
66
|
-
nil
|
67
|
-
end
|
68
|
-
|
69
|
-
if model_class
|
70
|
-
yaml_data.each do |_fixture_name, attributes|
|
71
|
-
model_class.create!(attributes)
|
72
|
-
rescue StandardError => e
|
73
|
-
raise ActiveRecord::InvalidForeignKey, e.message
|
74
|
-
end
|
75
|
-
else
|
76
|
-
Rails.logger.warn "[FixtureSeed] Model for table #{table_name} not found"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def log_loading(file)
|
81
|
-
Rails.logger.info "[FixtureSeed] Loading fixture #{File.basename(file)}..."
|
82
|
-
end
|
83
|
-
|
84
|
-
def log_success(file, original_files, current_files)
|
85
|
-
is_retry = original_files.size != current_files.size
|
86
|
-
if is_retry
|
87
|
-
Rails.logger.info "[FixtureSeed] Successfully loaded fixture #{File.basename(file)} on retry."
|
88
|
-
else
|
89
|
-
Rails.logger.info "[FixtureSeed] Loaded fixture #{File.basename(file)}"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def log_failure(file, error, original_files, current_files)
|
94
|
-
is_retry = original_files.size != current_files.size
|
95
|
-
filename = File.basename(file)
|
96
|
-
if is_retry
|
97
|
-
Rails.logger.warn "[FixtureSeed] Still failed to load fixture #{filename}: " \
|
98
|
-
"#{error.message}. Will retry later."
|
99
|
-
else
|
100
|
-
Rails.logger.warn "[FixtureSeed] Failed to load fixture #{filename}: " \
|
101
|
-
"#{error.message}. Will retry later."
|
102
|
-
end
|
103
|
-
end
|
10
|
+
def self.load_fixtures(fixtures_path = nil)
|
11
|
+
Loader.load_fixtures(fixtures_path)
|
104
12
|
end
|
105
13
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fixture_seed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masaki Komagata
|
@@ -36,6 +36,7 @@ files:
|
|
36
36
|
- LICENSE.txt
|
37
37
|
- README.md
|
38
38
|
- lib/fixture_seed.rb
|
39
|
+
- lib/fixture_seed/loader.rb
|
39
40
|
- lib/fixture_seed/railtie.rb
|
40
41
|
- lib/fixture_seed/version.rb
|
41
42
|
- sig/fixture_seed.rbs
|