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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3017e602e40c59de792d03c63f0d126c06abb63e54476329c1c88e9d36a6f57a
4
- data.tar.gz: c8c7267e55089bc38ae585e3d0329038a2416205da9ba9e4d9997674436ae891
3
+ metadata.gz: 74ef9a7ff52401cea08e20f1f6610eb509d339b8aabb7ae249a231f1818661e5
4
+ data.tar.gz: 3a7f4bbf8ea02c63979e01893dd7f03635fc164e046ec87035eb27b6525a9f80
5
5
  SHA512:
6
- metadata.gz: 6c7af8d978f4b93ce5175106c08522923e4e1e287d9aee354c432e6526a0e677f64d2cde17bff6dc53b9122f5c3cbb69033f03beaa826fdfd4f81c80d2412d24
7
- data.tar.gz: 57622614a7ed6514e1e9522ca62a11b2c69e3207f8caaa7e484f22757e994e3b44e4e3726d8ecd067134f7090f9c240a3f185e7f14f629170df23fe44bc2404f
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
@@ -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
- if Rake::Task.task_defined?("db:seed")
11
- Rake::Task["db:seed"].enhance([:load_fixtures])
12
-
13
- task :load_fixtures do
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FixtureSeed
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.1"
5
5
  end
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
- class << self
10
- def load_fixtures
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.2.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