lib/dirty_seed/seeder.rb in dirty_seed-0.2.0 vs lib/dirty_seed/seeder.rb in dirty_seed-0.2.1
- old
+ new
@@ -1,90 +1,118 @@
# frozen_string_literal: true
module DirtySeed
# Represents an Active Record model
class Seeder
- attr_reader :model, :instances, :errors
+ attr_reader :model, :records, :errors
- # Initializes an instance
+ # Initializes an record
# @param model [DirtySeed::Model]
# @return [DirtySeed::Seeder]
def initialize(model)
@model = model
- @instances = []
+ @records = []
@errors = []
end
# Creates records
# @param count [Integer]
# @return [Array<Object>]
- def seed(count)
- logger.seed(model)
- @count = count
+ def seed(qty = 1)
+ self.quantity = qty
+ logger.seed_model_message(model)
create_records
- @errors.uniq!
- instances
+ records
end
- # Returns the number of successfully seeded records
- # @return [Integer]
- def score
- instances.count
- end
-
- # Returns the errors as list
- # @return [String]
- def error_list
- errors.join(', ')
- end
-
private
+ attr_accessor :successive_errors, :quantity
+ attr_writer :errors
+
# Returns the logger
# @return [DirtySeed::Logger]
def logger
DirtySeed::Logger.instance
end
# Creates records
# @return [void]
+ # @note To take advantage of the faker uniqueness system, all params needs to be defined
+ # Then all records can be created with these params
+ # In other words: do not justcreate record one after the other
def create_records
- logger.start_line
- data = params_collection
- @count.times do |i|
- instance = model.new(data[i])
- save(instance)
- # rescue from errors on initialize
- rescue StandardError => e
- @errors << e.message
- logger.error
+ self.successive_errors = 0
+ params_collection.each do |params|
+ break if exceeded_successive_errors?
+
+ record = initialize_record(params)
+ record && save(record)
end
- logger.break_line
end
- # Tries to save instance in database
- # Populates instances and errors and log message
+ # Is the successive errors maximum reached?
+ # @return [Boolean]
+ # @note The purpose is to stop trying to seed if to many errors happen
+ def exceeded_successive_errors?
+ return false if successive_errors < 3
+
+ logger.abort
+ true
+ end
+
+ # Initialize a record
+ # @param params [Hash] params to pass to #new
+ # @return [Object] instance of model
+ def initialize_record(params)
+ model.new(params)
+ # rescue from errors on initialize
+ rescue StandardError => e
+ add_standard_error(e)
+ end
+
+ # Tries to save record in database
+ # Populates records and errors and log message
# @return [void]
- def save(instance)
- if instance.save
+ def save(record)
+ if record.save
+ records << record
+ self.successive_errors = 0
logger.success
- @instances << instance
else
- logger.fail
- @errors.concat(instance.errors.full_messages)
+ add_record_errors(record)
end
# rescue from errors on save
rescue StandardError => e
- @errors << e.message
- logger.error
+ add_standard_error(e)
end
+ # Adds record errors
+ # @param record [Object] instance of model
+ # @return [void]
+ def add_record_errors(record)
+ self.errors |= record.errors.full_messages
+ self.successive_errors = successive_errors + 1
+ logger.failure
+ end
+
+ # Adds standard error
+ # @param error [Error] error inheriting from StandardError
+ # @return [void]
+ def add_standard_error(error)
+ self.errors |= [logger.clean(error.message)]
+ self.successive_errors = successive_errors + 1
+ logger.failure
+ end
+
# Generate records params
# @return [Array<Hash>] where Hash is params for one record
+ # @note If model has no attributes and no associations, return empty hashes
def params_collection
data = Hash[attributes_collection + associations_collection]
- data.values.transpose.map { |vs| data.keys.zip(vs).to_h }
+ data = data.values.transpose.map { |vs| data.keys.zip(vs).to_h }
+ data.any? ? data : Array.new(quantity, {})
end
# Generate attributes params
# Each sub-array contains the attribute name and a collection of values
# @return [Array<Array>]
@@ -94,11 +122,11 @@
# [an_integer, [1, 2]]
# ]
def attributes_collection
model.attributes.map do |attribute|
Faker::UniqueGenerator.clear
- [attribute.name, Array.new(@count) { attribute.value }]
+ [attribute.name, Array.new(quantity) { attribute.value }]
end
end
# Generate associations params
# Each sub-array contains the association name and a collection of values
@@ -108,10 +136,10 @@
# ["alfa", [#<Alfa>, #<Alfa>]],
# ["bravo", [#<Bravo>, #<Bravo>]]
# ]
def associations_collection
model.associations.map do |association|
- [association.name, Array.new(@count) { association.value }]
+ [association.name, Array.new(quantity) { association.value }]
end
end
end
end