seedie 0.3.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 +71 -0
- data/Gemfile +4 -1
- data/README.md +7 -2
- data/Rakefile +1 -1
- data/lib/generators/seedie/install_generator.rb +28 -30
- data/lib/generators/seedie/templates/seedie_initializer.rb +1 -1
- 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 +3 -1
- 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 +26 -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 -18
- 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 +11 -28
- data/lib/tasks/seedie.rake +4 -2
- metadata +27 -11
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
module Associations
|
3
5
|
class HasOne < BaseAssociation
|
@@ -5,25 +7,23 @@ module Seedie
|
|
5
7
|
return if association_config["has_one"].nil?
|
6
8
|
|
7
9
|
report(:has_one_start)
|
8
|
-
|
10
|
+
|
9
11
|
association_config["has_one"].each do |association_name, association_config|
|
10
12
|
reflection = model.reflect_on_association(association_name)
|
11
13
|
association_class = reflection.klass
|
12
14
|
count = get_association_count(association_config)
|
13
|
-
|
15
|
+
|
14
16
|
report(:associated_records, count: count, name: association_name, parent_name: model.to_s)
|
15
|
-
if count > 1
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
record_creator.create!(field_values_set.merge!(parent_field_set))
|
24
|
-
end
|
17
|
+
raise InvalidAssociationConfigError, "has_one association cannot be more than 1" if count > 1
|
18
|
+
|
19
|
+
config = only_count_given?(association_config) ? {} : association_config
|
20
|
+
field_values_set = FieldValuesSet.new(association_class, config, INDEX).generate_field_values
|
21
|
+
parent_field_set = generate_associated_field(record.id, reflection.foreign_key)
|
22
|
+
|
23
|
+
record_creator = Model::Creator.new(association_class, reporters)
|
24
|
+
record_creator.create!(field_values_set.merge!(parent_field_set))
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
|
-
end
|
29
|
+
end
|
data/lib/seedie/configuration.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
module FieldValues
|
3
5
|
class CustomValue
|
4
|
-
VALID_KEYS = ["values", "value", "options"].freeze
|
5
|
-
PICK_STRATEGIES = ["random", "sequential"].freeze
|
6
|
-
|
7
6
|
attr_reader :name, :parsed_value
|
8
7
|
|
9
8
|
def initialize(name, value_template, index)
|
@@ -12,7 +11,7 @@ module Seedie
|
|
12
11
|
@index = index
|
13
12
|
@parsed_value = ""
|
14
13
|
|
15
|
-
|
14
|
+
ValueTemplateValidator.new(@value_template, @index, @name).validate
|
16
15
|
end
|
17
16
|
|
18
17
|
def generate_custom_field_value
|
@@ -27,89 +26,21 @@ module Seedie
|
|
27
26
|
|
28
27
|
private
|
29
28
|
|
30
|
-
def validate_value_template
|
31
|
-
return unless @value_template.is_a?(Hash)
|
32
|
-
|
33
|
-
validate_keys
|
34
|
-
validate_values if @value_template.key?("values")
|
35
|
-
validate_options if @value_template.key?("options")
|
36
|
-
end
|
37
|
-
|
38
|
-
def validate_values
|
39
|
-
values = @value_template["values"]
|
40
|
-
options = @value_template["options"]
|
41
|
-
|
42
|
-
if values.is_a?(Array) || values.is_a?(Hash)
|
43
|
-
validate_sequential_values_length
|
44
|
-
else
|
45
|
-
raise InvalidCustomFieldValuesError, "The values key for #{@name} must be an array or a hash with start and end keys."
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def validate_options
|
50
|
-
options = @value_template["options"]
|
51
|
-
pick_strategy = options["pick_strategy"]
|
52
|
-
|
53
|
-
if pick_strategy.present? && !PICK_STRATEGIES.include?(pick_strategy)
|
54
|
-
raise InvalidCustomFieldOptionsError,
|
55
|
-
"The pick_strategy for #{@name} must be either 'sequential' or 'random'."
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
## If pick strategy is sequential, we need to ensure there is a value for each index
|
60
|
-
# If there isn't sufficient values, we raise an error
|
61
|
-
def validate_sequential_values_length
|
62
|
-
return unless @value_template.key?("options")
|
63
|
-
return unless @value_template["options"]["pick_strategy"] == "sequential"
|
64
|
-
|
65
|
-
values = @value_template["values"]
|
66
|
-
|
67
|
-
if values.is_a?(Hash) && values.keys.sort == ["end", "start"]
|
68
|
-
# Assuming the values are an inclusive range
|
69
|
-
values_length = values["end"] - values["start"] + 1
|
70
|
-
else
|
71
|
-
values_length = values.length
|
72
|
-
end
|
73
|
-
|
74
|
-
if values_length < @index + 1
|
75
|
-
raise CustomFieldNotEnoughValuesError,
|
76
|
-
"There are not enough values for #{@name}. Please add more values."
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def validate_keys
|
81
|
-
invalid_keys = @value_template.keys - VALID_KEYS
|
82
|
-
|
83
|
-
if invalid_keys.present?
|
84
|
-
raise InvalidCustomFieldKeysError,
|
85
|
-
"Invalid keys for #{@name}: #{invalid_keys.join(", ")}. Only #{VALID_KEYS} are allowed."
|
86
|
-
end
|
87
|
-
|
88
|
-
if @value_template.key?("values")
|
89
|
-
if @value_template.key?("value")
|
90
|
-
raise InvalidCustomFieldKeysError,
|
91
|
-
"Invalid keys for #{@name}: values and value cannot be used together."
|
92
|
-
end
|
93
|
-
|
94
|
-
if @value_template["values"].is_a?(Hash)
|
95
|
-
if !@value_template["values"].key?("start") || !@value_template["values"].key?("end")
|
96
|
-
raise InvalidCustomFieldValuesError,
|
97
|
-
"The values key for #{@name} must be an array or a hash with start and end keys."
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
29
|
def generate_custom_value_from_string
|
104
30
|
@parsed_value = @value_template.gsub("{{index}}", @index.to_s)
|
105
31
|
|
106
32
|
@parsed_value.gsub!(/\{\{(.+?)\}\}/) do
|
107
|
-
method_string =
|
33
|
+
method_string = ::Regexp.last_match(1)
|
108
34
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
35
|
+
raise InvalidFakerMethodError, "Invalid method: #{method_string}" unless method_string.start_with?("Faker::")
|
36
|
+
|
37
|
+
method_chain = method_string.split(".")
|
38
|
+
# Faker::Name will be shifted off the array
|
39
|
+
faker_class = method_chain.shift.constantize
|
40
|
+
|
41
|
+
# For Faker::Internet.unique.email, there will be two methods in the array
|
42
|
+
method_chain.reduce(faker_class) do |current_class_or_value, method|
|
43
|
+
current_class_or_value.public_send(method)
|
113
44
|
end
|
114
45
|
end
|
115
46
|
end
|
@@ -123,7 +54,7 @@ module Seedie
|
|
123
54
|
generate_custom_values_from_range(@value_template["values"]["start"], @value_template["values"]["end"])
|
124
55
|
end
|
125
56
|
options = @value_template["options"]
|
126
|
-
|
57
|
+
|
127
58
|
if options.present? && options["pick_strategy"] == "sequential"
|
128
59
|
@parsed_value = values[@index]
|
129
60
|
else
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
module FieldValues
|
3
5
|
class FakeValue
|
@@ -9,41 +11,107 @@ module Seedie
|
|
9
11
|
def generate_fake_value
|
10
12
|
case @column.type
|
11
13
|
when :string, :text, :citext
|
12
|
-
|
14
|
+
generate_string
|
13
15
|
when :uuid
|
14
|
-
|
16
|
+
generate_uuid
|
15
17
|
when :integer, :bigint, :smallint
|
16
|
-
|
18
|
+
generate_integer
|
17
19
|
when :decimal, :float, :real
|
18
|
-
|
20
|
+
generate_decimal
|
19
21
|
when :datetime, :timestamp, :timestamptz
|
20
|
-
|
22
|
+
generate_datetime
|
21
23
|
when :date
|
22
|
-
|
24
|
+
generate_date
|
23
25
|
when :time, :timetz
|
24
|
-
|
26
|
+
generate_time
|
25
27
|
when :boolean
|
26
|
-
|
28
|
+
generate_boolean
|
27
29
|
when :json, :jsonb
|
28
|
-
|
30
|
+
generate_json
|
29
31
|
when :inet
|
30
|
-
|
32
|
+
generate_inet
|
31
33
|
when :cidr, :macaddr
|
32
|
-
|
34
|
+
generate_macaddr
|
33
35
|
when :bytea
|
34
|
-
|
36
|
+
generate_bytea
|
35
37
|
when :bit, :bit_varying
|
36
|
-
|
38
|
+
generate_bit
|
37
39
|
when :money
|
38
|
-
|
40
|
+
generate_money
|
39
41
|
when :hstore
|
40
|
-
|
42
|
+
generate_hstore
|
41
43
|
when :year
|
42
|
-
|
44
|
+
generate_year
|
43
45
|
else
|
44
46
|
raise UnknownColumnTypeError, "Unknown column type: #{@column.type}"
|
45
47
|
end
|
46
48
|
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def generate_string
|
53
|
+
Faker::Lorem.word
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_uuid
|
57
|
+
SecureRandom.uuid
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_integer
|
61
|
+
Faker::Number.number(digits: 5)
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_decimal
|
65
|
+
Faker::Number.decimal(l_digits: 2, r_digits: 2)
|
66
|
+
end
|
67
|
+
|
68
|
+
def generate_datetime
|
69
|
+
Faker::Time.between(from: DateTime.now - 1, to: DateTime.now)
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_date
|
73
|
+
Faker::Date.between(from: Date.today - 2, to: Date.today)
|
74
|
+
end
|
75
|
+
|
76
|
+
def generate_time
|
77
|
+
Faker::Time.forward(days: 23, period: :morning)
|
78
|
+
end
|
79
|
+
|
80
|
+
def generate_boolean
|
81
|
+
Faker::Boolean.boolean
|
82
|
+
end
|
83
|
+
|
84
|
+
def generate_json
|
85
|
+
{ "value" => { "key1" => Faker::Lorem.word, "key2" => Faker::Number.number(digits: 2) } }
|
86
|
+
end
|
87
|
+
|
88
|
+
def generate_inet
|
89
|
+
Faker::Internet.ip_v4_address
|
90
|
+
end
|
91
|
+
|
92
|
+
def generate_macaddr
|
93
|
+
Faker::Internet.mac_address
|
94
|
+
end
|
95
|
+
|
96
|
+
def generate_bytea
|
97
|
+
Faker::Internet.password
|
98
|
+
end
|
99
|
+
|
100
|
+
def generate_bit
|
101
|
+
%w[0 1].sample
|
102
|
+
end
|
103
|
+
|
104
|
+
def generate_money
|
105
|
+
Faker::Commerce.price.to_s
|
106
|
+
end
|
107
|
+
|
108
|
+
def generate_hstore
|
109
|
+
{ "value" => { "key1" => Faker::Lorem.word, "key2" => Faker::Number.number(digits: 2) } }
|
110
|
+
end
|
111
|
+
|
112
|
+
def generate_year
|
113
|
+
rand(1901..2155)
|
114
|
+
end
|
47
115
|
end
|
48
116
|
end
|
49
|
-
end
|
117
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seedie
|
2
4
|
module FieldValues
|
3
5
|
class FakerBuilder
|
@@ -17,11 +19,11 @@ module Seedie
|
|
17
19
|
return @seedie_config_custom_attributes[@name.to_sym] if @seedie_config_custom_attributes.key?(@name.to_sym)
|
18
20
|
|
19
21
|
@unique_prefix = "unique." if has_validation?(:uniqueness)
|
20
|
-
|
22
|
+
|
21
23
|
add_faker_class_and_method(@column.type)
|
22
|
-
|
24
|
+
|
23
25
|
if has_validation?(:inclusion)
|
24
|
-
handle_inclusion_validation
|
26
|
+
handle_inclusion_validation
|
25
27
|
else
|
26
28
|
@options += handle_numericality_validation if has_validation?(:numericality)
|
27
29
|
@options += handle_length_validation if has_validation?(:length)
|
@@ -40,58 +42,46 @@ module Seedie
|
|
40
42
|
def add_faker_class_and_method(type)
|
41
43
|
case type
|
42
44
|
when :string, :text, :citext
|
43
|
-
|
44
|
-
@method_prefix = "word"
|
45
|
+
set_faker("Lorem.", "word")
|
45
46
|
when :uuid
|
46
|
-
|
47
|
-
@method_prefix = "uuid"
|
47
|
+
set_faker("Internet.", "uuid")
|
48
48
|
when :integer, :bigint, :smallint
|
49
|
-
|
50
|
-
@method_prefix = "number"
|
51
|
-
@options = "(digits: 5)"
|
49
|
+
set_faker("Number.", "number", "(digits: 5)")
|
52
50
|
when :decimal, :float, :real
|
53
|
-
|
54
|
-
@method_prefix = "decimal"
|
55
|
-
@options = "(l_digits: 2, r_digits: 2)"
|
51
|
+
set_faker("Number.", "decimal", "(l_digits: 2, r_digits: 2)")
|
56
52
|
when :datetime, :timestamp, :timestamptz, :time, :timetz
|
57
|
-
|
58
|
-
@method_prefix = "between"
|
59
|
-
@options = "(from: DateTime.now - 1, to: DateTime.now)"
|
53
|
+
set_faker("Time.", "between", "(from: DateTime.now - 1, to: DateTime.now)")
|
60
54
|
when :date
|
61
|
-
|
62
|
-
@method_prefix = "between"
|
63
|
-
@options = "(from: Date.today - 1, to: Date.today)"
|
55
|
+
set_faker("Date.", "between", "(from: Date.today - 1, to: Date.today)")
|
64
56
|
when :boolean
|
65
|
-
|
66
|
-
@method_prefix = "boolean"
|
57
|
+
set_faker("Boolean.", "boolean")
|
67
58
|
when :json, :jsonb
|
68
59
|
@faker_expression = { "value" => "Json.shallow_json(width: 3, options: { key: 'Name.first_name', value: 'Number.number(digits: 2)' })" }
|
69
60
|
when :inet
|
70
|
-
|
71
|
-
@method_prefix = "ip_v4_address"
|
61
|
+
set_faker("Internet.", "ip_v4_address")
|
72
62
|
when :cidr, :macaddr
|
73
|
-
|
74
|
-
@method_prefix = "mac_address"
|
63
|
+
set_faker("Internet.", "mac_address")
|
75
64
|
when :bytea
|
76
|
-
|
77
|
-
@method_prefix = "password"
|
65
|
+
set_faker("Internet.", "password")
|
78
66
|
when :bit, :bit_varying
|
79
|
-
|
80
|
-
@method_prefix = "password"
|
67
|
+
set_faker("Internet.", "password")
|
81
68
|
when :money
|
82
|
-
|
83
|
-
@method_prefix = "price.to_s"
|
69
|
+
set_faker("Commerce.", "price.to_s")
|
84
70
|
when :hstore
|
85
71
|
@faker_expression = { "value" => "Json.shallow_json(width: 3, options: { key: 'Name.first_name', value: 'Number.number(digits: 2)' })" }
|
86
72
|
when :year
|
87
|
-
|
88
|
-
@method_prefix = "number"
|
89
|
-
@options = "(digits: 4)"
|
73
|
+
set_faker("Number.", "number", "(digits: 4)")
|
90
74
|
else
|
91
75
|
raise UnknownColumnTypeError, "Unknown column type: #{type}"
|
92
76
|
end
|
93
77
|
end
|
94
78
|
|
79
|
+
def set_faker(class_prefix, method_prefix, options = "")
|
80
|
+
@class_prefix = class_prefix
|
81
|
+
@method_prefix = method_prefix
|
82
|
+
@options = options
|
83
|
+
end
|
84
|
+
|
95
85
|
def has_validation?(kind)
|
96
86
|
@validations.any? { |validation| validation.kind == kind }
|
97
87
|
end
|
@@ -132,7 +122,8 @@ module Seedie
|
|
132
122
|
@method_prefix = ""
|
133
123
|
@options = ""
|
134
124
|
if options[:in].is_a?(Range)
|
135
|
-
@faker_expression = { "values" => { "start" => options[:in].first, "end" => options[:in].last },
|
125
|
+
@faker_expression = { "values" => { "start" => options[:in].first, "end" => options[:in].last },
|
126
|
+
"options" => { "pick_strategy" => "random" } }
|
136
127
|
else
|
137
128
|
@faker_expression = { "values" => options[:in], "options" => { "pick_strategy" => "random" } }
|
138
129
|
end
|
@@ -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
|