seedie 0.2.0 → 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/.rubocop.yml +91 -9
- data/CHANGELOG.md +123 -0
- data/Gemfile +4 -1
- data/README.md +77 -3
- data/Rakefile +1 -1
- data/lib/generators/seedie/install_generator.rb +84 -37
- data/lib/generators/seedie/templates/blank_seedie.yml +22 -0
- data/lib/generators/seedie/templates/seedie_initializer.rb +8 -0
- data/lib/seedie/associations/base_association.rb +35 -31
- data/lib/seedie/associations/belongs_to.rb +12 -13
- data/lib/seedie/associations/has_and_belongs_to_many.rb +26 -0
- data/lib/seedie/associations/has_many.rb +6 -4
- data/lib/seedie/associations/has_one.rb +13 -13
- data/lib/seedie/configuration.rb +12 -0
- data/lib/seedie/field_values/custom_value.rb +14 -83
- data/lib/seedie/field_values/fake_value.rb +85 -17
- data/lib/seedie/field_values/faker_builder.rb +29 -35
- data/lib/seedie/field_values/value_template_validator.rb +91 -0
- data/lib/seedie/field_values_set.rb +21 -4
- data/lib/seedie/model/creator.rb +7 -5
- data/lib/seedie/model/id_generator.rb +10 -8
- data/lib/seedie/model/model_sorter.rb +14 -19
- data/lib/seedie/model_fields.rb +5 -3
- data/lib/seedie/model_seeder.rb +11 -22
- data/lib/seedie/polymorphic_association_helper.rb +20 -16
- data/lib/seedie/railtie.rb +3 -2
- data/lib/seedie/reporters/base_reporter.rb +75 -68
- data/lib/seedie/reporters/console_reporter.rb +16 -12
- data/lib/seedie/reporters/reportable.rb +14 -10
- data/lib/seedie/seeder.rb +5 -3
- data/lib/seedie/version.rb +1 -1
- data/lib/seedie.rb +21 -27
- data/lib/tasks/seedie.rake +4 -2
- metadata +32 -13
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Seedie
|
4
|
+
module FieldValues
|
5
|
+
class ValueTemplateValidator
|
6
|
+
VALID_KEYS = %w[values value options].freeze
|
7
|
+
PICK_STRATEGIES = %w[random sequential].freeze
|
8
|
+
|
9
|
+
def initialize(value_template, index, name)
|
10
|
+
@value_template = value_template
|
11
|
+
@index = index
|
12
|
+
@name = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate
|
16
|
+
return unless @value_template.is_a?(Hash)
|
17
|
+
|
18
|
+
validate_keys
|
19
|
+
validate_values if @value_template.key?("values")
|
20
|
+
validate_options if @value_template.key?("options")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def validate_keys
|
26
|
+
invalid_keys = @value_template.keys - VALID_KEYS
|
27
|
+
|
28
|
+
if invalid_keys.present?
|
29
|
+
raise InvalidCustomFieldKeysError,
|
30
|
+
"Invalid keys for #{@name}: #{invalid_keys.join(', ')}. Only #{VALID_KEYS} are allowed."
|
31
|
+
end
|
32
|
+
|
33
|
+
return unless @value_template.key?("values")
|
34
|
+
|
35
|
+
if @value_template.key?("value")
|
36
|
+
raise InvalidCustomFieldKeysError,
|
37
|
+
"Invalid keys for #{@name}: values and value cannot be used together."
|
38
|
+
end
|
39
|
+
|
40
|
+
return unless @value_template["values"].is_a?(Hash)
|
41
|
+
|
42
|
+
return unless !@value_template["values"].key?("start") || !@value_template["values"].key?("end")
|
43
|
+
|
44
|
+
raise InvalidCustomFieldValuesError,
|
45
|
+
"The values key for #{@name} must be an array or a hash with start and end keys."
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate_values
|
49
|
+
values = @value_template["values"]
|
50
|
+
|
51
|
+
unless values.is_a?(Array) || values.is_a?(Hash)
|
52
|
+
raise InvalidCustomFieldValuesError,
|
53
|
+
"The values key for #{@name} must be an array or a hash with start and end keys."
|
54
|
+
end
|
55
|
+
|
56
|
+
validate_sequential_values_length
|
57
|
+
end
|
58
|
+
|
59
|
+
def validate_options
|
60
|
+
options = @value_template["options"]
|
61
|
+
pick_strategy = options["pick_strategy"]
|
62
|
+
|
63
|
+
return unless pick_strategy.present? && !PICK_STRATEGIES.include?(pick_strategy)
|
64
|
+
|
65
|
+
raise InvalidCustomFieldOptionsError,
|
66
|
+
"The pick_strategy for #{@name} must be either 'sequential' or 'random'."
|
67
|
+
end
|
68
|
+
|
69
|
+
## If pick strategy is sequential, we need to ensure there is a value for each index
|
70
|
+
# If there isn't sufficient values, we raise an error
|
71
|
+
def validate_sequential_values_length
|
72
|
+
return unless @value_template.key?("options")
|
73
|
+
return unless @value_template["options"]["pick_strategy"] == "sequential"
|
74
|
+
|
75
|
+
values = @value_template["values"]
|
76
|
+
|
77
|
+
values_length = if values.is_a?(Hash) && values.keys.sort == %w[end start]
|
78
|
+
# Assuming the values are an inclusive range
|
79
|
+
values["end"] - values["start"] + 1
|
80
|
+
else
|
81
|
+
values.length
|
82
|
+
end
|
83
|
+
|
84
|
+
return unless values_length < @index + 1
|
85
|
+
|
86
|
+
raise CustomFieldNotEnoughValuesError,
|
87
|
+
"There are not enough values for #{@name}. Please add more values."
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
class FieldValuesSet
|
3
|
-
attr_reader :attributes_config, :index
|
5
|
+
attr_reader :model, :model_config, :attributes_config, :index
|
4
6
|
|
5
7
|
def initialize(model, model_config, index)
|
6
8
|
@model = model
|
@@ -18,6 +20,12 @@ module Seedie
|
|
18
20
|
@field_values
|
19
21
|
end
|
20
22
|
|
23
|
+
def generate_field_values_with_associations
|
24
|
+
associated_field_values_set = generate_belongs_to_associations
|
25
|
+
model_field_values_set = generate_field_values
|
26
|
+
model_field_values_set.merge!(associated_field_values_set)
|
27
|
+
end
|
28
|
+
|
21
29
|
def generate_field_value(name, column)
|
22
30
|
return generate_custom_field_value(name) if @attributes_config&.key?(name)
|
23
31
|
|
@@ -26,18 +34,27 @@ module Seedie
|
|
26
34
|
|
27
35
|
private
|
28
36
|
|
37
|
+
def generate_belongs_to_associations
|
38
|
+
associations_config = model_config["associations"]
|
39
|
+
return {} unless associations_config.present?
|
40
|
+
|
41
|
+
belongs_to_associations = Associations::BelongsTo.new(model, associations_config)
|
42
|
+
belongs_to_associations.generate_associations
|
43
|
+
belongs_to_associations.associated_field_set
|
44
|
+
end
|
45
|
+
|
29
46
|
def populate_values_for_model_fields
|
30
47
|
@field_values = @model.columns_hash.map do |name, column|
|
31
48
|
next if @model_fields.disabled_fields.include?(name)
|
32
49
|
next if @model_fields.foreign_fields.include?(name)
|
33
|
-
|
50
|
+
|
34
51
|
[name, generate_field_value(name, column)]
|
35
52
|
end.compact.to_h
|
36
53
|
end
|
37
54
|
|
38
55
|
def populate_values_for_virtual_fields
|
39
56
|
virtual_fields = @attributes_config.keys - @model.columns_hash.keys
|
40
|
-
|
57
|
+
|
41
58
|
virtual_fields.each do |name|
|
42
59
|
@field_values[name] = generate_custom_field_value(name) if @attributes_config[name]
|
43
60
|
end
|
@@ -47,4 +64,4 @@ module Seedie
|
|
47
64
|
FieldValues::CustomValue.new(name, @attributes_config[name], @index).generate_custom_field_value
|
48
65
|
end
|
49
66
|
end
|
50
|
-
end
|
67
|
+
end
|
data/lib/seedie/model/creator.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
module Model
|
3
5
|
class Creator
|
4
6
|
include Reporters::Reportable
|
5
|
-
|
7
|
+
|
6
8
|
def initialize(model, reporters = [])
|
7
9
|
@model = model
|
8
10
|
@reporters = reporters
|
9
11
|
|
10
12
|
add_observers(@reporters)
|
11
13
|
end
|
12
|
-
|
14
|
+
|
13
15
|
def create!(field_values_set)
|
14
16
|
record = @model.create!(field_values_set)
|
15
|
-
report(:record_created, name:
|
17
|
+
report(:record_created, name: record.class.to_s, id: record.id.to_s)
|
16
18
|
|
17
19
|
record
|
18
20
|
end
|
@@ -22,9 +24,9 @@ module Seedie
|
|
22
24
|
create!(field_values_set)
|
23
25
|
rescue ActiveRecord::RecordInvalid => e
|
24
26
|
report(:record_invalid, record: e.record)
|
25
|
-
|
27
|
+
nil
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
30
|
-
end
|
32
|
+
end
|
@@ -1,30 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
module Model
|
3
5
|
class IdGenerator
|
4
6
|
def initialize(model)
|
5
7
|
@model = model
|
6
8
|
end
|
7
|
-
|
9
|
+
|
8
10
|
def random_id
|
9
11
|
id = @model.pluck(:id).sample
|
10
12
|
raise InvalidAssociationConfigError, "#{@model} has no records" unless id
|
11
13
|
|
12
|
-
|
14
|
+
id
|
13
15
|
end
|
14
|
-
|
16
|
+
|
15
17
|
def unique_id_for(association_klass, model_id_column)
|
16
18
|
unless association_klass.column_names.include?(model_id_column)
|
17
|
-
raise InvalidAssociationConfigError, "#{model_id_column} does not exist in #{association_klass}"
|
19
|
+
raise InvalidAssociationConfigError, "#{model_id_column} does not exist in #{association_klass}"
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
unique_ids = @model.ids - association_klass.pluck(model_id_column)
|
21
|
-
|
23
|
+
|
22
24
|
if unique_ids.empty?
|
23
25
|
raise InvalidAssociationConfigError, "No unique ids for #{@model}"
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
unique_ids.first
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
30
|
-
end
|
32
|
+
end
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
module Model
|
3
5
|
class ModelSorter
|
4
6
|
include PolymorphicAssociationHelper
|
5
|
-
|
7
|
+
|
6
8
|
def initialize(models)
|
7
9
|
@models = models
|
8
|
-
@model_dependencies = models.map {|m| [m, get_model_dependencies(m)]}.to_h
|
10
|
+
@model_dependencies = models.map { |m| [m, get_model_dependencies(m)] }.to_h
|
9
11
|
@resolved_queue = []
|
10
12
|
@unresolved = []
|
11
13
|
end
|
12
|
-
|
14
|
+
|
13
15
|
def sort_by_dependency
|
14
16
|
add_independent_models_to_queue
|
15
17
|
|
@@ -19,9 +21,8 @@ module Seedie
|
|
19
21
|
|
20
22
|
@resolved_queue
|
21
23
|
end
|
22
|
-
|
23
|
-
private
|
24
24
|
|
25
|
+
private
|
25
26
|
|
26
27
|
# Independent models need to be added first
|
27
28
|
def add_independent_models_to_queue
|
@@ -31,7 +32,7 @@ module Seedie
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
def resolve_dependencies(model)
|
36
37
|
if @unresolved.include?(model)
|
37
38
|
puts "Circular dependency detected for #{model}. Ignoring..."
|
@@ -39,25 +40,21 @@ module Seedie
|
|
39
40
|
end
|
40
41
|
|
41
42
|
@unresolved << model
|
42
|
-
|
43
|
-
|
44
|
-
if dependencies
|
45
|
-
dependencies.each do |dependency|
|
46
|
-
resolve_dependencies(dependency) unless @resolved_queue.include?(dependency)
|
47
|
-
end
|
43
|
+
@model_dependencies[model]&.each do |dependency|
|
44
|
+
resolve_dependencies(dependency) unless @resolved_queue.include?(dependency)
|
48
45
|
end
|
49
46
|
|
50
47
|
@resolved_queue << model
|
51
48
|
@unresolved.delete(model)
|
52
49
|
end
|
53
|
-
|
50
|
+
|
54
51
|
def get_model_dependencies(model)
|
55
52
|
associations = model.reflect_on_all_associations(:belongs_to).reject do |association|
|
56
53
|
association.options[:optional] == true # Excluded Optional Associations
|
57
54
|
end
|
58
|
-
|
55
|
+
|
59
56
|
return [] if associations.blank?
|
60
|
-
|
57
|
+
|
61
58
|
associations.map do |association|
|
62
59
|
if association.options[:class_name]
|
63
60
|
constantize_class_name(association.options[:class_name], model.name)
|
@@ -65,7 +62,7 @@ module Seedie
|
|
65
62
|
types = find_polymorphic_types(model, association.name)
|
66
63
|
|
67
64
|
if types.blank?
|
68
|
-
puts "Polymorphic type not found for #{model.name}. Ignoring..."
|
65
|
+
puts "Polymorphic type not found for #{model.name}. Ignoring..."
|
69
66
|
next
|
70
67
|
end
|
71
68
|
else
|
@@ -74,8 +71,6 @@ module Seedie
|
|
74
71
|
end.compact
|
75
72
|
end
|
76
73
|
|
77
|
-
private
|
78
|
-
|
79
74
|
def constantize_class_name(class_name, model_name)
|
80
75
|
namespaced_class_name = if model_name.include?("::")
|
81
76
|
"#{model_name.deconstantize}::#{class_name}"
|
@@ -90,6 +85,6 @@ module Seedie
|
|
90
85
|
class_name.constantize
|
91
86
|
end
|
92
87
|
end
|
93
|
-
end
|
88
|
+
end
|
94
89
|
end
|
95
90
|
end
|
data/lib/seedie/model_fields.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
class ModelFields
|
3
|
-
DEFAULT_DISABLED_FIELDS = %w[id created_at updated_at]
|
5
|
+
DEFAULT_DISABLED_FIELDS = %w[id created_at updated_at].freeze
|
4
6
|
|
5
7
|
attr_reader :model_name, :model_config, :fields, :disabled_fields, :foreign_fields
|
6
|
-
|
8
|
+
|
7
9
|
def initialize(model, model_config)
|
8
10
|
@model_name = model.to_s
|
9
11
|
@model_config = model_config
|
@@ -13,4 +15,4 @@ module Seedie
|
|
13
15
|
@other_fields = model.column_names - @disabled_fields - @custom_fields - @foreign_fields
|
14
16
|
end
|
15
17
|
end
|
16
|
-
end
|
18
|
+
end
|
data/lib/seedie/model_seeder.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
class ModelSeeder
|
3
5
|
include Reporters::Reportable
|
@@ -12,22 +14,22 @@ module Seedie
|
|
12
14
|
@config = config
|
13
15
|
@record_creator = Model::Creator.new(model, reporters)
|
14
16
|
@reporters = reporters
|
15
|
-
|
16
17
|
add_observers(@reporters)
|
17
18
|
end
|
18
19
|
|
19
20
|
def generate_records
|
20
|
-
report(:model_seed_start, name:
|
21
|
+
report(:model_seed_start, name: model.to_s)
|
21
22
|
model_count(model_config).times do |index|
|
22
23
|
record = generate_record(model_config, index)
|
23
24
|
associations_config = model_config["associations"]
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
next unless associations_config.present?
|
27
|
+
|
28
|
+
Associations::HasMany.new(record, model, associations_config, reporters).generate_associations
|
29
|
+
Associations::HasAndBelongsToMany.new(record, model, associations_config, reporters).generate_associations
|
30
|
+
Associations::HasOne.new(record, model, associations_config, reporters).generate_associations
|
29
31
|
end
|
30
|
-
report(:model_seed_finish, name:
|
32
|
+
report(:model_seed_finish, name: model.to_s)
|
31
33
|
end
|
32
34
|
|
33
35
|
private
|
@@ -40,21 +42,8 @@ module Seedie
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def generate_record(model_config, index)
|
43
|
-
|
44
|
-
|
45
|
-
field_values_set = FieldValuesSet.new(model, model_config, index).generate_field_values
|
46
|
-
field_values_set.merge!(associated_field_set)
|
45
|
+
field_values_set = FieldValuesSet.new(model, model_config, index).generate_field_values_with_associations
|
47
46
|
@record_creator.create!(field_values_set)
|
48
47
|
end
|
49
|
-
|
50
|
-
def generate_belongs_to_associations(model, model_config)
|
51
|
-
associations_config = model_config["associations"]
|
52
|
-
return {} unless associations_config.present?
|
53
|
-
|
54
|
-
belongs_to_associations = Associations::BelongsTo.new(model, associations_config, reporters)
|
55
|
-
belongs_to_associations.generate_associations
|
56
|
-
|
57
|
-
return belongs_to_associations.associated_field_set
|
58
|
-
end
|
59
48
|
end
|
60
|
-
end
|
49
|
+
end
|
@@ -1,20 +1,24 @@
|
|
1
|
-
|
2
|
-
# Returns the type of the polymorphic association
|
3
|
-
# We need only one polymorphic association while generating config
|
4
|
-
# this makes it easier to sort according to dependencies
|
5
|
-
def find_polymorphic_types(model, association_name)
|
6
|
-
type = @models.find { |potential_model| has_association?(potential_model, association_name) }
|
7
|
-
type&.name&.underscore
|
8
|
-
end
|
1
|
+
# frozen_string_literal: true
|
9
2
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
module Seedie
|
4
|
+
module PolymorphicAssociationHelper
|
5
|
+
# Returns the type of the polymorphic association
|
6
|
+
# We need only one polymorphic association while generating config
|
7
|
+
# this makes it easier to sort according to dependencies
|
8
|
+
def find_polymorphic_types(_model, association_name)
|
9
|
+
type = @models.find { |potential_model| has_association?(potential_model, association_name) }
|
10
|
+
type&.name&.underscore
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_association?(model, association_name)
|
14
|
+
associations = select_associations(model)
|
15
|
+
associations.any? { |association| association.options[:as] == association_name }
|
16
|
+
end
|
17
|
+
|
18
|
+
def select_associations(model)
|
19
|
+
model.reflect_on_all_associations.select do |reflection|
|
20
|
+
%i[has_many has_one].include?(reflection.macro)
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
data/lib/seedie/railtie.rb
CHANGED
@@ -1,81 +1,88 @@
|
|
1
|
-
|
2
|
-
class BaseReporter
|
3
|
-
INDENT_SIZE = 2
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
3
|
+
module Seedie
|
4
|
+
module Reporters
|
5
|
+
class BaseReporter
|
6
|
+
INDENT_SIZE = 2
|
6
7
|
|
7
|
-
|
8
|
-
@output = output || StringIO.new
|
9
|
-
@reports = []
|
10
|
-
@indent_level = 0
|
11
|
-
end
|
8
|
+
attr_reader :output, :reports
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def initialize(output = nil)
|
11
|
+
@output = output || StringIO.new
|
12
|
+
@reports = []
|
13
|
+
@indent_level = 0
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
16
|
+
def update(event_type, options)
|
17
|
+
raise NotImplementedError, "Subclasses must define 'update'."
|
18
|
+
end
|
21
19
|
|
22
|
-
|
20
|
+
def close
|
21
|
+
return if output.closed?
|
23
22
|
|
24
|
-
|
25
|
-
case event_type
|
26
|
-
when :seed_start
|
27
|
-
"############ SEEDIE RUNNING #############"
|
28
|
-
when :seed_finish
|
29
|
-
"############ SEEDIE FINISHED ############"
|
30
|
-
when :model_seed_start
|
31
|
-
"Seeding #{options[:name]}"
|
32
|
-
when :model_seed_finish
|
33
|
-
"Seeding #{options[:name]} finished!"
|
34
|
-
when :record_created
|
35
|
-
"Created #{options[:name]} with id: #{options[:id]}"
|
36
|
-
when :has_many_start
|
37
|
-
"Creating HasMany associations:"
|
38
|
-
when :belongs_to_start
|
39
|
-
"Creating BelongsTo associations:"
|
40
|
-
when :has_one_start
|
41
|
-
"Creating HasOne associations:"
|
42
|
-
when :associated_records
|
43
|
-
"Creating #{options[:count]} #{options[:name]} for #{options[:parent_name]}"
|
44
|
-
when :random_association
|
45
|
-
"Randomly associating #{options[:name]} with id: #{options[:id]} for #{options[:parent_name]}"
|
46
|
-
when :unique_association
|
47
|
-
"Uniquely associating #{options[:name]} for #{options[:parent_name]}"
|
48
|
-
when :belongs_to_associations
|
49
|
-
"Creating a new #{options[:name].titleize} for #{options[:parent_name]}"
|
50
|
-
else
|
51
|
-
"Unknown event type"
|
23
|
+
output.flush
|
52
24
|
end
|
53
|
-
end
|
54
25
|
|
55
|
-
|
56
|
-
indent_levels = {
|
57
|
-
seed_start: 0,
|
58
|
-
seed_finish: 0,
|
59
|
-
model_seed_start: 1,
|
60
|
-
model_seed_finish: 1,
|
61
|
-
record_created: 1,
|
62
|
-
random_association: 1,
|
63
|
-
has_many_start: 2,
|
64
|
-
belongs_to_start: 2,
|
65
|
-
has_one_start: 2,
|
66
|
-
associated_records: 3,
|
67
|
-
belongs_to_associations: 3
|
68
|
-
}
|
26
|
+
private
|
69
27
|
|
70
|
-
|
71
|
-
|
28
|
+
def messages(event_type, options)
|
29
|
+
case event_type
|
30
|
+
when :seed_start
|
31
|
+
"############ SEEDIE RUNNING #############"
|
32
|
+
when :seed_finish
|
33
|
+
"############ SEEDIE FINISHED ############"
|
34
|
+
when :model_seed_start
|
35
|
+
"Seeding #{options[:name]}"
|
36
|
+
when :model_seed_finish
|
37
|
+
"Seeding #{options[:name]} finished!"
|
38
|
+
when :record_created
|
39
|
+
"Created #{options[:name]} with id: #{options[:id]}"
|
40
|
+
when :has_many_start
|
41
|
+
"Creating HasMany associations:"
|
42
|
+
when :belongs_to_start
|
43
|
+
"Creating BelongsTo associations:"
|
44
|
+
when :has_one_start
|
45
|
+
"Creating HasOne associations:"
|
46
|
+
when :has_and_belongs_to_many_start
|
47
|
+
"Creating HasAndBelongsToMany associations:"
|
48
|
+
when :associated_records
|
49
|
+
"Creating #{options[:count]} #{options[:name]} for #{options[:parent_name]}"
|
50
|
+
when :random_association
|
51
|
+
"Randomly associating #{options[:name]} with id: #{options[:id]} for #{options[:parent_name]}"
|
52
|
+
when :unique_association
|
53
|
+
"Uniquely associating #{options[:name]} for #{options[:parent_name]}"
|
54
|
+
when :belongs_to_associations
|
55
|
+
"Creating a new #{options[:name].titleize} for #{options[:parent_name]}"
|
56
|
+
else
|
57
|
+
"Unknown event type"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def indent_level_for(event_type)
|
62
|
+
indent_levels = {
|
63
|
+
seed_start: 0,
|
64
|
+
seed_finish: 0,
|
65
|
+
model_seed_start: 1,
|
66
|
+
model_seed_finish: 1,
|
67
|
+
record_created: 1,
|
68
|
+
random_association: 1,
|
69
|
+
has_many_start: 2,
|
70
|
+
belongs_to_start: 2,
|
71
|
+
has_one_start: 2,
|
72
|
+
associated_records: 3,
|
73
|
+
belongs_to_associations: 3
|
74
|
+
}
|
75
|
+
|
76
|
+
indent_levels[event_type]
|
77
|
+
end
|
72
78
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
79
|
+
def update_indent_level(event_type)
|
80
|
+
if event_type.in?(%i[record_created random_association unique_association])
|
81
|
+
@indent_level += 1 if !@reports.last[:event_type].in?(%i[record_created random_association unique_association])
|
82
|
+
elsif @reports.blank? || @reports.last[:event_type] != event_type
|
83
|
+
@indent_level = indent_level_for(event_type)
|
84
|
+
end
|
78
85
|
end
|
79
86
|
end
|
80
87
|
end
|
81
|
-
end
|
88
|
+
end
|
@@ -1,16 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Seedie
|
4
|
+
module Reporters
|
5
|
+
class ConsoleReporter < BaseReporter
|
6
|
+
def initialize
|
7
|
+
super($stdout)
|
8
|
+
end
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
def update(event_type, options)
|
11
|
+
update_indent_level(event_type)
|
12
|
+
message = messages(event_type, options)
|
13
|
+
@reports << { event_type: event_type, message: message }
|
11
14
|
|
12
|
-
|
13
|
-
|
15
|
+
output.print "#{' ' * INDENT_SIZE * @indent_level}"
|
16
|
+
output.puts message
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
|
-
end
|
20
|
+
end
|
@@ -1,16 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "observer"
|
2
4
|
|
3
|
-
module
|
4
|
-
module
|
5
|
-
|
5
|
+
module Seedie
|
6
|
+
module Reporters
|
7
|
+
module Reportable
|
8
|
+
include Observable
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
def report(event_type, options = {})
|
11
|
+
changed
|
12
|
+
notify_observers(event_type, options)
|
13
|
+
end
|
11
14
|
|
12
|
-
|
13
|
-
|
15
|
+
def add_observers(observers)
|
16
|
+
observers.each { |observer| add_observer(observer) }
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
|
-
end
|
20
|
+
end
|