better_seeder 0.2.3 → 0.2.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 +3 -1
- data/lib/better_seeder/builders/structure.rb +15 -16
- data/lib/better_seeder/configuration.rb +4 -4
- data/lib/better_seeder/exporters/base.rb +7 -5
- data/lib/better_seeder/exporters/csv.rb +3 -0
- data/lib/better_seeder/exporters/json.rb +3 -3
- data/lib/better_seeder/exporters/sql.rb +4 -1
- data/lib/better_seeder/farms/farmer.rb +23 -24
- data/lib/better_seeder/structure/utils.rb +2 -0
- data/lib/better_seeder/utils.rb +44 -6
- data/lib/better_seeder/version.rb +1 -1
- data/lib/better_seeder.rb +56 -55
- data/lib/generators/better_seeder/structure_generator.rb +6 -4
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5b13470c3a8af2c331ef6254593d3268c5a82654802368c4af18608ad629185
|
4
|
+
data.tar.gz: ba63f74f95445e8b29bab7e33757c9ed460786a655fb9402733b0a7372436086
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e215fd763c8348003cff4266ba1616eca6e3430e586c754b150ae2f68c97e969c23eec7ad946fd1ba7a1656feb3c507667ef45195834cd531546ea7ecba9e42
|
7
|
+
data.tar.gz: fc8b41742698a0cd0cf9b3db03a8b57bc2342b528bde096affe737a856f2a329b66063d5130b6b5a618caa1f8c87c169f60064ca4400575514ee1eca4e115feb
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# lib/better_seeder/generators/structure_generator.rb
|
2
4
|
require 'fileutils'
|
3
5
|
|
@@ -5,8 +7,8 @@ module BetterSeeder
|
|
5
7
|
module Builders
|
6
8
|
class Structure
|
7
9
|
TEMPLATE = <<~RUBY
|
8
|
-
module
|
9
|
-
class
|
10
|
+
module %<module_name>s
|
11
|
+
class %<class_name>sStructure < ::BetterSeeder::Structure::Utils
|
10
12
|
# Defines generators for each attribute.
|
11
13
|
def self.structure
|
12
14
|
{
|
@@ -23,15 +25,15 @@ module BetterSeeder
|
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
|
-
# Specific seeding configuration for
|
28
|
+
# Specific seeding configuration for %<class_name>s.
|
27
29
|
def self.seed_config
|
28
30
|
{
|
29
|
-
file_name: '
|
31
|
+
file_name: '%<file_name>s',
|
30
32
|
columns: { excluded: [] },
|
31
33
|
generate_data: true,
|
32
34
|
count: 10,
|
33
35
|
load_data: true,
|
34
|
-
|
36
|
+
# parents: [ { model: 'MyNamespace::MyModel', column: :my_column } ]
|
35
37
|
}
|
36
38
|
end
|
37
39
|
|
@@ -49,26 +51,23 @@ module BetterSeeder
|
|
49
51
|
# @return [String] The full path to the generated file.
|
50
52
|
def self.generate(model_name)
|
51
53
|
# Split the model name into module parts and the actual class name.
|
52
|
-
parts
|
53
|
-
class_name
|
54
|
-
module_name = parts.empty? ?
|
54
|
+
parts = model_name.split('::')
|
55
|
+
class_name = parts.pop
|
56
|
+
module_name = parts.empty? ? 'Main' : parts.join('::')
|
55
57
|
|
56
58
|
# Determine the file path.
|
57
59
|
# For example, for "MyNamespace::MyModel", the file will be placed in:
|
58
60
|
# lib/better_seeder/generators/my_namespace/my_model_structure.rb
|
59
61
|
folder_path = File.join(BetterSeeder.configuration.structure_path, *parts.map(&:underscore))
|
60
|
-
file_name
|
61
|
-
full_path
|
62
|
+
file_name = "#{class_name.underscore}_structure.rb"
|
63
|
+
full_path = File.join(folder_path, file_name)
|
62
64
|
|
63
65
|
# Ensure the target directory exists.
|
64
|
-
FileUtils.mkdir_p(folder_path)
|
66
|
+
FileUtils.mkdir_p(folder_path)
|
65
67
|
|
66
68
|
# Prepare the file content.
|
67
|
-
content = TEMPLATE
|
68
|
-
|
69
|
-
class_name: class_name,
|
70
|
-
file_name: "#{class_name.underscore}_seed"
|
71
|
-
}
|
69
|
+
content = format(TEMPLATE, module_name: module_name, class_name: class_name,
|
70
|
+
file_name: "#{class_name.underscore}_seed")
|
72
71
|
|
73
72
|
# Write the template to the file.
|
74
73
|
File.write(full_path, content)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# lib/better_seeder/configuration.rb
|
2
4
|
|
3
5
|
module BetterSeeder
|
@@ -5,14 +7,12 @@ module BetterSeeder
|
|
5
7
|
attr_accessor :log_language, :log_level, :structure_path, :preload_path
|
6
8
|
|
7
9
|
def initialize
|
10
|
+
@log_language = :en
|
11
|
+
@log_level = :info
|
8
12
|
if defined?(Rails) && Rails.respond_to?(:root)
|
9
|
-
@log_language = :en
|
10
|
-
@log_level = :info
|
11
13
|
@structure_path = Rails.root.join('db', 'seed', 'structure')
|
12
14
|
@preload_path = Rails.root.join('db', 'seed', 'preload')
|
13
15
|
else
|
14
|
-
@log_language = :en
|
15
|
-
@log_level = :info
|
16
16
|
@structure_path = File.join(Dir.pwd, 'db', 'seed', 'structure')
|
17
17
|
@preload_path = File.join(Dir.pwd, 'db', 'seed', 'preload')
|
18
18
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# lib/better_seeder/exporter/base_exporter.rb
|
2
4
|
|
3
5
|
module BetterSeeder
|
@@ -23,10 +25,10 @@ module BetterSeeder
|
|
23
25
|
# @param output_path [String] Nome del file (senza estensione).
|
24
26
|
# @param table_name [String] Nome della tabella (usato in SqlExporter).
|
25
27
|
def initialize(data, output_path:, table_name: 'my_table')
|
26
|
-
@data
|
28
|
+
@data = data
|
27
29
|
# Utilizza il preload_path definito nella configurazione BetterSeeder (impostato nell'initializer).
|
28
30
|
@output_path = File.join(BetterSeeder.configuration.preload_path, output_path)
|
29
|
-
@table_name
|
31
|
+
@table_name = table_name
|
30
32
|
end
|
31
33
|
|
32
34
|
# Restituisce la directory in cui salvare i file.
|
@@ -39,7 +41,7 @@ module BetterSeeder
|
|
39
41
|
|
40
42
|
# Verifica che la directory di output esista; se non esiste, la crea.
|
41
43
|
def ensure_output_directory
|
42
|
-
FileUtils.mkdir_p(output_directory)
|
44
|
+
FileUtils.mkdir_p(output_directory)
|
43
45
|
end
|
44
46
|
|
45
47
|
# Costruisce il percorso completo del file di output, combinando la directory, l'output_path e l'estensione.
|
@@ -53,12 +55,12 @@ module BetterSeeder
|
|
53
55
|
# Metodo astratto per ottenere l'estensione del file (es. ".json", ".csv", ".sql").
|
54
56
|
# Le classi derivate devono implementarlo.
|
55
57
|
def extension
|
56
|
-
raise NotImplementedError,
|
58
|
+
raise NotImplementedError, 'Subclasses must implement #extension'
|
57
59
|
end
|
58
60
|
|
59
61
|
# Metodo astratto per effettuare l'export.
|
60
62
|
def export
|
61
|
-
raise NotImplementedError,
|
63
|
+
raise NotImplementedError, 'Subclasses must implement the export method'
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module BetterSeeder
|
2
4
|
module Exporters
|
3
5
|
class Csv < Base
|
@@ -5,6 +7,7 @@ module BetterSeeder
|
|
5
7
|
# Se la cartella non esiste, viene creata automaticamente.
|
6
8
|
def export
|
7
9
|
return if data.empty?
|
10
|
+
|
8
11
|
headers = data.first.keys
|
9
12
|
|
10
13
|
# Costruisce il percorso completo del file di output
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module BetterSeeder
|
2
4
|
module Exporters
|
3
5
|
class Json < Base
|
@@ -7,9 +9,7 @@ module BetterSeeder
|
|
7
9
|
# Imposta la directory di output
|
8
10
|
full_path = File.join(full_output_path)
|
9
11
|
|
10
|
-
File.
|
11
|
-
file.write(JSON.pretty_generate(data))
|
12
|
-
end
|
12
|
+
File.write(full_path, JSON.pretty_generate(data))
|
13
13
|
end
|
14
14
|
|
15
15
|
def extension
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module BetterSeeder
|
2
4
|
module Exporters
|
3
5
|
class Sql < Base
|
@@ -11,6 +13,7 @@ module BetterSeeder
|
|
11
13
|
# ... ;
|
12
14
|
def export
|
13
15
|
return if data.empty?
|
16
|
+
|
14
17
|
columns = data.first.keys
|
15
18
|
|
16
19
|
# Crea l'array delle tuple di valori per ciascun record.
|
@@ -18,7 +21,7 @@ module BetterSeeder
|
|
18
21
|
row_values = columns.map do |col|
|
19
22
|
value = row[col]
|
20
23
|
# Se il valore è nil restituisce NULL, altrimenti esegue l'escaping delle virgolette singole.
|
21
|
-
value.nil? ?
|
24
|
+
value.nil? ? 'NULL' : "'#{value.to_s.gsub("'", "''")}'"
|
22
25
|
end
|
23
26
|
"(#{row_values.join(', ')})"
|
24
27
|
end
|
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module BetterSeeder
|
2
4
|
module Farms
|
3
5
|
class Farmer
|
4
|
-
|
5
6
|
class << self
|
6
7
|
def generate(options = {})
|
7
|
-
model_name = options[:model] or raise ArgumentError,
|
8
|
-
count
|
8
|
+
model_name = options[:model] or raise ArgumentError, 'Missing :model option'
|
9
|
+
count = options[:count] || 10
|
9
10
|
|
10
11
|
# Costruisce il percorso del file di structure.
|
11
12
|
structure_file = File.expand_path(
|
@@ -35,7 +36,7 @@ module BetterSeeder
|
|
35
36
|
new_record = build_record(model_name, structure_class)
|
36
37
|
new_record = inject_parent_keys(model_name, new_record, structure_class)
|
37
38
|
break if validate_record(new_record, structure_class) &&
|
38
|
-
|
39
|
+
!record_exists?(model_name, new_record, structure_class, generated_records)
|
39
40
|
end
|
40
41
|
generated_records.push(new_record)
|
41
42
|
end
|
@@ -45,16 +46,17 @@ module BetterSeeder
|
|
45
46
|
|
46
47
|
private
|
47
48
|
|
48
|
-
def record_exists?(
|
49
|
+
def record_exists?(_model_name, record, structure_class, generated_records)
|
49
50
|
# Se non è definito il metodo unique_keys, non eseguiamo il controllo
|
50
51
|
return false unless structure_class.respond_to?(:unique_keys)
|
52
|
+
|
51
53
|
unique_key_sets = structure_class.unique_keys
|
52
54
|
return false if unique_key_sets.empty?
|
53
55
|
|
54
56
|
# Determina il modello associato: si assume che il nome del modello sia
|
55
57
|
# dato dalla rimozione della stringa "Structure" dal nome della classe di structure.
|
56
58
|
model_class_name = structure_class.to_s.sub(/Structure$/, '')
|
57
|
-
model_class
|
59
|
+
model_class = Object.const_get(model_class_name)
|
58
60
|
|
59
61
|
# Per ogni set di chiavi uniche, costruiamo le condizioni della query
|
60
62
|
unique_key_sets.each do |key_set|
|
@@ -72,41 +74,39 @@ module BetterSeeder
|
|
72
74
|
false
|
73
75
|
end
|
74
76
|
|
75
|
-
def build_record(
|
77
|
+
def build_record(_model_name, structure_class)
|
76
78
|
generation_rules = structure_class.structure
|
77
|
-
raise
|
79
|
+
raise 'Structure must be a Hash' unless generation_rules.is_a?(Hash)
|
78
80
|
|
79
81
|
record = {}
|
80
82
|
generation_rules.each do |attribute, rule|
|
81
83
|
# Ogni rule è un array nel formato [tipo, generatore]
|
82
|
-
generator
|
83
|
-
value
|
84
|
+
generator = rule[1]
|
85
|
+
value = generator.respond_to?(:call) ? generator.call : generator
|
84
86
|
record[attribute] = value
|
85
87
|
end
|
86
88
|
|
87
89
|
record
|
88
90
|
end
|
89
91
|
|
90
|
-
def inject_parent_keys(
|
91
|
-
config
|
92
|
+
def inject_parent_keys(_model_name, record, structure_class)
|
93
|
+
config = structure_class.respond_to?(:seed_config) ? structure_class.seed_config : {}
|
92
94
|
parents_spec = config[:parents]
|
93
|
-
return record
|
95
|
+
return record if parents_spec.blank?
|
94
96
|
|
95
97
|
parents_spec.each do |parent_config|
|
96
98
|
parent_model = parent_config[:model]
|
97
|
-
column
|
99
|
+
column = parent_config[:column]
|
98
100
|
|
99
101
|
# Tenta di ottenere un record del parent dal pool BetterSeeder.generated_records se disponibile.
|
100
102
|
# Usiamo il nome del modello come chiave nel pool.
|
101
|
-
pool_key
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
BetterSeeder.generated_records[pool_key].sample
|
109
|
-
end
|
103
|
+
pool_key = parent_model.to_s
|
104
|
+
unless defined?(BetterSeeder.generated_records) &&
|
105
|
+
BetterSeeder.generated_records[pool_key] &&
|
106
|
+
!BetterSeeder.generated_records[pool_key].empty?
|
107
|
+
BetterSeeder.generated_records[pool_key] = parent_model.all
|
108
|
+
end
|
109
|
+
parent_record = BetterSeeder.generated_records[pool_key].sample
|
110
110
|
|
111
111
|
raise "Parent record not found for #{parent_model}" unless parent_record
|
112
112
|
|
@@ -127,7 +127,6 @@ module BetterSeeder
|
|
127
127
|
|
128
128
|
raise result.errors.to_h
|
129
129
|
end
|
130
|
-
|
131
130
|
end
|
132
131
|
end
|
133
132
|
end
|
data/lib/better_seeder/utils.rb
CHANGED
@@ -1,18 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# lib/better_seeder/utils.rb
|
4
|
+
#
|
5
|
+
# = BetterSeeder::Utils
|
6
|
+
#
|
7
|
+
# Questo modulo fornisce metodi di utilità per la gestione dei seed. In particolare,
|
8
|
+
# consente di trasformare i nomi delle classi in formato snake_case con il suffisso "_structure.rb",
|
9
|
+
# gestire i messaggi di log e configurare il livello del logger per ActiveRecord.
|
2
10
|
|
3
11
|
module BetterSeeder
|
4
12
|
module Utils
|
5
|
-
|
6
13
|
class << self
|
7
|
-
|
8
|
-
#
|
14
|
+
##
|
15
|
+
# Trasforma un nome di classe in snake_case e aggiunge il suffisso "_structure.rb".
|
16
|
+
#
|
17
|
+
# ==== Esempio
|
18
|
+
# transform_class_name("Campaigns::Campaign")
|
19
|
+
# # => "campaigns/campaign_structure.rb"
|
20
|
+
#
|
21
|
+
# ==== Parametri
|
22
|
+
# * +class_name+ - Stringa che rappresenta il nome della classe, eventualmente suddiviso in
|
23
|
+
# namespace separati da "::".
|
24
|
+
#
|
25
|
+
# ==== Ritorno
|
26
|
+
# Restituisce una stringa con il nome della classe in formato snake_case e l'ultimo elemento
|
27
|
+
# terminato con "_structure.rb".
|
28
|
+
#
|
9
29
|
def transform_class_name(class_name)
|
10
|
-
elements
|
30
|
+
elements = class_name.split('::').map(&:underscore)
|
11
31
|
# Aggiunge "_structure.rb" all'ultimo elemento
|
12
32
|
elements[-1] = "#{elements[-1]}_structure.rb"
|
13
|
-
elements.join(
|
33
|
+
elements.join('/')
|
14
34
|
end
|
15
35
|
|
36
|
+
##
|
37
|
+
# Registra un messaggio usando il logger di Rails se disponibile, altrimenti lo stampa su standard output.
|
38
|
+
#
|
39
|
+
# ==== Parametri
|
40
|
+
# * +message+ - Il messaggio da loggare (può essere una stringa o nil).
|
41
|
+
#
|
42
|
+
# ==== Ritorno
|
43
|
+
# Non ritorna un valore significativo.
|
44
|
+
#
|
16
45
|
def logger(message: nil)
|
17
46
|
if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
|
18
47
|
Rails.logger.info message
|
@@ -21,6 +50,16 @@ module BetterSeeder
|
|
21
50
|
end
|
22
51
|
end
|
23
52
|
|
53
|
+
##
|
54
|
+
# Configura il livello del logger per ActiveRecord in base alla configurazione definita in BetterSeeder.
|
55
|
+
#
|
56
|
+
# ==== Dettagli
|
57
|
+
# Il metodo imposta il livello del logger in base al valore di BetterSeeder.configuration.log_level:
|
58
|
+
# * +:debug+ -> Logger::DEBUG
|
59
|
+
# * +:info+ -> Logger::INFO
|
60
|
+
# * +:error+ -> Logger::ERROR
|
61
|
+
# Se il livello non corrisponde a nessuna delle opzioni previste, viene impostato il livello +Logger::DEBUG+.
|
62
|
+
#
|
24
63
|
def log_level_setup
|
25
64
|
level = case BetterSeeder.configuration.log_level
|
26
65
|
when :debug then Logger::DEBUG
|
@@ -31,7 +70,6 @@ module BetterSeeder
|
|
31
70
|
|
32
71
|
ActiveRecord::Base.logger.level = level
|
33
72
|
end
|
34
|
-
|
35
73
|
end
|
36
74
|
end
|
37
75
|
end
|
data/lib/better_seeder.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'better_seeder/utils'
|
4
|
+
require_relative 'better_seeder/configuration'
|
5
|
+
require_relative 'better_seeder/structure/utils'
|
6
|
+
require_relative 'better_seeder/farms/farmer'
|
7
|
+
require_relative 'better_seeder/exporters/base'
|
8
|
+
require_relative 'better_seeder/exporters/json'
|
9
|
+
require_relative 'better_seeder/exporters/csv'
|
10
|
+
require_relative 'better_seeder/exporters/sql'
|
11
|
+
require_relative 'better_seeder/builders/structure'
|
10
12
|
|
11
13
|
module BetterSeeder
|
12
14
|
class Configuration
|
13
15
|
attr_accessor :log_language, :structure_path, :preload_path
|
14
16
|
|
15
17
|
def initialize
|
18
|
+
@log_language = :en
|
19
|
+
@log_level = :info
|
16
20
|
if defined?(Rails) && Rails.respond_to?(:root)
|
17
|
-
@log_language = :en
|
18
|
-
@log_level = :info
|
19
21
|
@structure_path = Rails.root.join('db', 'seed', 'structure')
|
20
|
-
@preload_path
|
22
|
+
@preload_path = Rails.root.join('db', 'seed', 'preload')
|
21
23
|
else
|
22
|
-
@log_language = :en
|
23
|
-
@log_level = :info
|
24
24
|
@structure_path = File.join(Dir.pwd, 'db', 'seed', 'structure')
|
25
|
-
@preload_path
|
25
|
+
@preload_path = File.join(Dir.pwd, 'db', 'seed', 'preload')
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -65,7 +65,7 @@ module BetterSeeder
|
|
65
65
|
# - structure_path: percorso dove sono memorizzati i file di structure (default: Rails.root/db/seed/structure)
|
66
66
|
# - preload_path: percorso dove verranno salvati i file esportati (default: Rails.root/db/seed/preload)
|
67
67
|
def self.install
|
68
|
-
initializer_path =
|
68
|
+
initializer_path = Rails.root.join('config', 'initializers', 'better_seeder.rb').to_s
|
69
69
|
|
70
70
|
if File.exist?(initializer_path)
|
71
71
|
message = "BetterSeeder initializer already exists at #{initializer_path}"
|
@@ -116,8 +116,8 @@ module BetterSeeder
|
|
116
116
|
message = "[LOGGER] previous log level: #{previous_log_level}, actual log level: #{ActiveRecord::Base.logger.level}"
|
117
117
|
BetterSeeder::Utils.logger(message: message)
|
118
118
|
|
119
|
-
start_time
|
120
|
-
stats
|
119
|
+
start_time = Time.zone.now
|
120
|
+
stats = {} # Statistiche: modello => numero di record caricati
|
121
121
|
parent_loaded_records = {} # Per memorizzare i record creati per i modelli parent
|
122
122
|
|
123
123
|
ActiveRecord::Base.transaction do
|
@@ -129,7 +129,7 @@ module BetterSeeder
|
|
129
129
|
end
|
130
130
|
|
131
131
|
ActiveRecord::Base.logger.level = previous_log_level
|
132
|
-
total_time
|
132
|
+
total_time = Time.zone.now - start_time
|
133
133
|
log_statistics(stats, total_time)
|
134
134
|
end
|
135
135
|
|
@@ -137,8 +137,6 @@ module BetterSeeder
|
|
137
137
|
BetterSeeder::Builders::Structure.generate(model_name)
|
138
138
|
end
|
139
139
|
|
140
|
-
private
|
141
|
-
|
142
140
|
# Processa la configurazione per un singolo modello.
|
143
141
|
# Carica il file di structure corrispondente e recupera la configurazione tramite `seed_config`.
|
144
142
|
# Quindi, esegue il recupero o la generazione dei record, iniezione di eventuali foreign key per modelli child,
|
@@ -168,18 +166,18 @@ module BetterSeeder
|
|
168
166
|
|
169
167
|
# Recupera la configurazione specifica dal file di structure tramite il metodo seed_config.
|
170
168
|
# Se non definito, vengono usati dei valori di default.
|
171
|
-
seed_config
|
172
|
-
file_name
|
173
|
-
excluded_columns = if export_type.to_s.downcase
|
174
|
-
seed_config.dig(:columns, :excluded) || []
|
175
|
-
else
|
169
|
+
seed_config = structure_class.respond_to?(:seed_config) ? structure_class.seed_config : {}
|
170
|
+
file_name = seed_config[:file_name] || "#{model_name.underscore}_seed"
|
171
|
+
excluded_columns = if export_type.to_s.downcase == 'sql'
|
176
172
|
[]
|
173
|
+
else
|
174
|
+
seed_config.dig(:columns, :excluded) || []
|
177
175
|
end
|
178
|
-
generate_data
|
179
|
-
count
|
180
|
-
load_data
|
181
|
-
parent
|
182
|
-
superclass
|
176
|
+
generate_data = seed_config.fetch(:generate_data, true)
|
177
|
+
count = seed_config[:count] || 10
|
178
|
+
load_data = seed_config.fetch(:load_data, true)
|
179
|
+
parent = seed_config[:parent] # nil oppure valore (o array) per modelli child
|
180
|
+
superclass = seed_config[:superclass] # nil oppure valore (o array) per modelli child
|
183
181
|
|
184
182
|
# Log per indicare se il modello è parent o child.
|
185
183
|
message = if parent.nil?
|
@@ -190,7 +188,11 @@ module BetterSeeder
|
|
190
188
|
BetterSeeder::Utils.logger(message: message)
|
191
189
|
|
192
190
|
# Recupera la classe reale del modello (ActiveRecord).
|
193
|
-
model_class =
|
191
|
+
model_class = begin
|
192
|
+
Object.const_get(model_name)
|
193
|
+
rescue StandardError
|
194
|
+
nil
|
195
|
+
end
|
194
196
|
unless model_class
|
195
197
|
message = "[ERROR] Model #{model_name} not found."
|
196
198
|
BetterSeeder::Utils.logger(message: message)
|
@@ -199,32 +201,31 @@ module BetterSeeder
|
|
199
201
|
end
|
200
202
|
|
201
203
|
# Se abilitato, carica i record nel database.
|
202
|
-
if load_data && File.exist?("#{BetterSeeder.configuration.preload_path
|
204
|
+
if load_data && File.exist?("#{BetterSeeder.configuration.preload_path}/#{seed_config[:file_name]}.sql")
|
203
205
|
load_data_from_file(seed_config)
|
204
|
-
stats[model_name] = model_class.
|
206
|
+
stats[model_name] = model_class.count
|
207
|
+
elsif generate_data
|
208
|
+
records = Farms::Farmer.generate(model: model_name, count: count)
|
209
|
+
total_records = records.size
|
210
|
+
stats[model_name] = total_records
|
211
|
+
created_records = load_records_into_db(model_class, records, total_records, model_name,
|
212
|
+
superclass)
|
213
|
+
# Se il modello è parent, salva i record creati per poterli utilizzare in seguito per i modelli child.
|
214
|
+
parent_loaded_records[model_name] = created_records if parent.nil?
|
205
215
|
else
|
206
|
-
|
207
|
-
records = Farms::Farmer.generate(model: model_name, count: count)
|
208
|
-
total_records = records.size
|
209
|
-
stats[model_name] = total_records
|
210
|
-
created_records = load_records_into_db(model_class, records, total_records, model_name, superclass)
|
211
|
-
# Se il modello è parent, salva i record creati per poterli utilizzare in seguito per i modelli child.
|
212
|
-
parent_loaded_records[model_name] = created_records if parent.nil?
|
213
|
-
else
|
214
|
-
model_class.all.map(&:attributes)
|
215
|
-
end
|
216
|
+
model_class.all.map(&:attributes)
|
216
217
|
end
|
217
218
|
|
218
219
|
# Rimuove le colonne escluse.
|
219
|
-
|
220
|
-
processed_records = BetterSeeder.generated_records[(superclass || model_name).to_s]
|
221
|
-
processed_records = processed_records.map do |campaign|
|
222
|
-
campaign.attributes.except(*excluded_columns.map(&:to_s))
|
223
|
-
end
|
220
|
+
return if BetterSeeder.generated_records[(superclass || model_name).to_s].nil?
|
224
221
|
|
225
|
-
|
226
|
-
|
222
|
+
processed_records = BetterSeeder.generated_records[(superclass || model_name).to_s]
|
223
|
+
processed_records = processed_records.map do |campaign|
|
224
|
+
campaign.attributes.except(*excluded_columns.map(&:to_s))
|
227
225
|
end
|
226
|
+
|
227
|
+
# Esporta i record nel formato richiesto.
|
228
|
+
export_records(model_class, processed_records, export_type, file_name)
|
228
229
|
end
|
229
230
|
|
230
231
|
# Carica i record nel database, utilizzando una progress bar per monitorare il progresso.
|
@@ -233,7 +234,7 @@ module BetterSeeder
|
|
233
234
|
# @return [Array<Object>] Array dei record creati (istanze ActiveRecord)
|
234
235
|
def self.load_records_into_db(model_class, processed_records, total_records, model_name, superclass)
|
235
236
|
progressbar = ProgressBar.create(total: total_records, format: '%a %B %p%% %t')
|
236
|
-
message
|
237
|
+
message = "[INFO] Starting to load #{total_records} records for model #{model_name}..."
|
237
238
|
BetterSeeder::Utils.logger(message: message)
|
238
239
|
|
239
240
|
processed_records.each do |record|
|
@@ -270,14 +271,14 @@ module BetterSeeder
|
|
270
271
|
# Log finale con le statistiche raccolte e il tempo totale di esecuzione.
|
271
272
|
def self.log_statistics(stats, total_time)
|
272
273
|
stats_message = stats.map { |model, count| "#{model}: #{count} records" }.join("\n")
|
273
|
-
message
|
274
|
+
message = "[INFO] Finished processing all models in #{total_time.round(2)} seconds. Statistics: \n#{stats_message}"
|
274
275
|
BetterSeeder::Utils.logger(message: message)
|
275
276
|
end
|
276
277
|
|
277
278
|
# Metodo di utilità per trasformare il nome della classe in un formato in cui le lettere
|
278
279
|
# sono in minuscolo e separate da underscore.
|
279
280
|
def self.transform_class_name(class_name)
|
280
|
-
class_name.split(
|
281
|
+
class_name.split('::').map(&:underscore).join('_')
|
281
282
|
end
|
282
283
|
|
283
284
|
def self.load_data_from_file(seed_config)
|
@@ -299,7 +300,7 @@ module BetterSeeder
|
|
299
300
|
ActiveRecord::Base.connection.execute(sql)
|
300
301
|
BetterSeeder::Utils.logger(message: "[INFO] Loaded seed file: #{seed_file_path}")
|
301
302
|
true
|
302
|
-
rescue => e
|
303
|
+
rescue StandardError => e
|
303
304
|
BetterSeeder::Utils.logger(message: "[ERROR] Failed to load seed file: #{seed_file_path} - Error: #{e.message}")
|
304
305
|
false
|
305
306
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# lib/generators/better_seeder/structure_generator.rb
|
2
|
-
require
|
4
|
+
require 'rails/generators'
|
3
5
|
|
4
6
|
module BetterSeeder
|
5
7
|
class StructureGenerator < Rails::Generators::NamedBase
|
@@ -7,9 +9,9 @@ module BetterSeeder
|
|
7
9
|
# source_root File.expand_path("templates", __dir__)
|
8
10
|
|
9
11
|
def create_structure_file
|
10
|
-
say_status(
|
12
|
+
say_status('info', "Generating structure file for #{name}", :green)
|
11
13
|
file_path = BetterSeeder.generate_structure(model_name: name)
|
12
|
-
say_status(
|
14
|
+
say_status('info', "Structure file created at #{file_path}", :green)
|
13
15
|
end
|
14
16
|
end
|
15
|
-
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: better_seeder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.3
|
4
|
+
version: 0.2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alessio_bussolari
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-02-
|
11
|
+
date: 2025-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: dry-schema
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: dry-
|
28
|
+
name: dry-types
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: ffaker
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.19'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.19'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: ruby-progressbar
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.11'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: activerecord
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '4.2'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: activesupport
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -151,6 +151,7 @@ metadata:
|
|
151
151
|
homepage_uri: https://github.com/alessiobussolari/better_seeder
|
152
152
|
source_code_uri: https://github.com/alessiobussolari/better_seeder
|
153
153
|
changelog_uri: https://github.com/alessiobussolari/better_seeder/blob/main/CHANGELOG.md
|
154
|
+
rubygems_mfa_required: 'true'
|
154
155
|
post_install_message:
|
155
156
|
rdoc_options: []
|
156
157
|
require_paths:
|