dirty_seed 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +44 -0
- data/Rakefile +22 -0
- data/lib/dirty_seed.rb +23 -0
- data/lib/dirty_seed/assigners/dirty_assigner.rb +32 -0
- data/lib/dirty_seed/assigners/dirty_boolean.rb +14 -0
- data/lib/dirty_seed/assigners/dirty_date.rb +14 -0
- data/lib/dirty_seed/assigners/dirty_float.rb +28 -0
- data/lib/dirty_seed/assigners/dirty_integer.rb +86 -0
- data/lib/dirty_seed/assigners/dirty_string.rb +49 -0
- data/lib/dirty_seed/assigners/dirty_time.rb +14 -0
- data/lib/dirty_seed/data_model.rb +80 -0
- data/lib/dirty_seed/dirty_association.rb +106 -0
- data/lib/dirty_seed/dirty_attribute.rb +64 -0
- data/lib/dirty_seed/dirty_model.rb +123 -0
- data/lib/dirty_seed/engine.rb +11 -0
- data/lib/dirty_seed/exceptions.rb +6 -0
- data/lib/dirty_seed/method_missing_helper.rb +49 -0
- data/lib/dirty_seed/sorter.rb +118 -0
- data/lib/dirty_seed/version.rb +6 -0
- data/lib/tasks/dirty_seed_tasks.rake +8 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/javascript/packs/application.js +15 -0
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/alfa.rb +5 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/bravo.rb +3 -0
- data/spec/dummy/app/models/charlie.rb +5 -0
- data/spec/dummy/app/models/delta.rb +4 -0
- data/spec/dummy/app/models/echo.rb +3 -0
- data/spec/dummy/app/models/foxtrot.rb +2 -0
- data/spec/dummy/app/models/golf.rb +2 -0
- data/spec/dummy/app/models/hotel.rb +4 -0
- data/spec/dummy/app/models/india.rb +4 -0
- data/spec/dummy/app/models/juliett.rb +21 -0
- data/spec/dummy/app/models/kilo.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +18 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +62 -0
- data/spec/dummy/config/environments/production.rb +112 -0
- data/spec/dummy/config/environments/test.rb +49 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +12 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +27 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +38 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20200923100317_create_alfas.rb +15 -0
- data/spec/dummy/db/migrate/20200923100328_create_bravos.rb +12 -0
- data/spec/dummy/db/migrate/20200923100329_create_charlies.rb +9 -0
- data/spec/dummy/db/migrate/20200923100330_create_deltas.rb +10 -0
- data/spec/dummy/db/migrate/20200923100331_create_echos.rb +9 -0
- data/spec/dummy/db/migrate/20200923100332_create_foxtrots.rb +9 -0
- data/spec/dummy/db/migrate/20200923100334_create_hotels.rb +7 -0
- data/spec/dummy/db/migrate/20200923100335_create_indias.rb +11 -0
- data/spec/dummy/db/migrate/20200923100336_create_julietts.rb +11 -0
- data/spec/dummy/db/migrate/20200923100337_create_kilos.rb +13 -0
- data/spec/dummy/db/schema.rb +105 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +217 -0
- data/spec/dummy/log/test.log +95379 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/factories/bars.rb +8 -0
- data/spec/dummy/spec/factories/foos.rb +7 -0
- data/spec/dummy/spec/models/alfa_spec.rb +6 -0
- data/spec/dummy/spec/models/bravo_spec.rb +6 -0
- data/spec/dummy/spec/models/charlie_spec.rb +6 -0
- data/spec/dummy/spec/models/delta_spec.rb +6 -0
- data/spec/dummy/spec/models/echo_spec.rb +6 -0
- data/spec/dummy/tmp/development_secret.txt +1 -0
- data/spec/lib/dirty_seed/assigners/dirty_assigner_spec.rb +13 -0
- data/spec/lib/dirty_seed/assigners/dirty_boolean_spec.rb +13 -0
- data/spec/lib/dirty_seed/assigners/dirty_date_spec.rb +15 -0
- data/spec/lib/dirty_seed/assigners/dirty_float_spec.rb +47 -0
- data/spec/lib/dirty_seed/assigners/dirty_integer_spec.rb +49 -0
- data/spec/lib/dirty_seed/assigners/dirty_string_spec.rb +15 -0
- data/spec/lib/dirty_seed/assigners/dirty_time_spec.rb +15 -0
- data/spec/lib/dirty_seed/data_model_spec.rb +72 -0
- data/spec/lib/dirty_seed/dirty_association_spec.rb +64 -0
- data/spec/lib/dirty_seed/dirty_attribute_spec.rb +49 -0
- data/spec/lib/dirty_seed/dirty_model_spec.rb +102 -0
- data/spec/lib/dirty_seed/sorter_spec.rb +46 -0
- data/spec/lib/tasks/dirty_seed_tasks_spec.rb +21 -0
- data/spec/rails_helper.rb +44 -0
- data/spec/support/helpers.rb +30 -0
- metadata +282 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e9767e646a1b92174c3a4428716ba9fc4214cf882d7f60f938b6d1545113695d
|
4
|
+
data.tar.gz: 7eae0d2328c0e848d81579a2d054a380c38e773025e4c9cd04fefab20e780c8d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48f999e45dc0138d58d39533fe1f4d5c275d6f9ba810fc4eef10040780ec5b30272509ab9b4bb1c9b8edf4d8836adf41e69ae2add9f98a1ee5cb44a24485958a
|
7
|
+
data.tar.gz: 63921534da52c1bc42fae353ac1c6a38d2af20cac8213d7c31c9e849b7d86f933e729cddde4b65a5d8d49411b4344bae8acb3e1bba313ea74c75095b8937fc23
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2020 Edouard Piron
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
> **Work in progress!**
|
2
|
+
|
3
|
+
# DirtySeed
|
4
|
+
|
5
|
+
Populate the database with records matching associations and validations, in order to quickly test application.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Once you've installed the gem, you can use the dedicated task.
|
10
|
+
|
11
|
+
To seed dirty data, run:
|
12
|
+
```bash
|
13
|
+
$ rake dirty_seed:seed
|
14
|
+
```
|
15
|
+
|
16
|
+
This will try to create instances for each of your models inheriting from `ApplicationRecord`.
|
17
|
+
|
18
|
+
If the instance cannot be saved, it is simply ignored.
|
19
|
+
|
20
|
+
Number of instances created and recurrent errors will be outputed.
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
gem 'dirty_seed', git: 'https://github.com/BigBigDoudou/dirty_seed'
|
28
|
+
```
|
29
|
+
|
30
|
+
And then execute:
|
31
|
+
```bash
|
32
|
+
$ bundle
|
33
|
+
```
|
34
|
+
|
35
|
+
## License
|
36
|
+
|
37
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
38
|
+
|
39
|
+
## Next features
|
40
|
+
|
41
|
+
* Assign values for more data types (json, array, etc.).
|
42
|
+
* Integrate more validations (uniqueness, inclusion, length, absence, etc.).
|
43
|
+
* Use instance errors to adjust values.
|
44
|
+
* Add a configuration system to define how to seed: number of instances, models to skip, default values, etc.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'DirtySeed'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
load 'rails/tasks/statistics.rake'
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
data/lib/dirty_seed.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'dirty_seed/engine'
|
4
|
+
require_relative 'dirty_seed/exceptions'
|
5
|
+
|
6
|
+
module DirtySeed
|
7
|
+
autoload :MethodMissingHelper, 'dirty_seed/method_missing_helper'
|
8
|
+
autoload :DataModel, 'dirty_seed/data_model'
|
9
|
+
autoload :DirtyModel, 'dirty_seed/dirty_model'
|
10
|
+
autoload :DirtyAssociation, 'dirty_seed/dirty_association'
|
11
|
+
autoload :DirtyAttribute, 'dirty_seed/dirty_attribute'
|
12
|
+
autoload :Sorter, 'dirty_seed/sorter'
|
13
|
+
|
14
|
+
module Assigners
|
15
|
+
autoload :DirtyAssigner, 'dirty_seed/assigners/dirty_assigner'
|
16
|
+
autoload :DirtyBoolean, 'dirty_seed/assigners/dirty_boolean'
|
17
|
+
autoload :DirtyInteger, 'dirty_seed/assigners/dirty_integer'
|
18
|
+
autoload :DirtyFloat, 'dirty_seed/assigners/dirty_float'
|
19
|
+
autoload :DirtyString, 'dirty_seed/assigners/dirty_string'
|
20
|
+
autoload :DirtyDate, 'dirty_seed/assigners/dirty_date'
|
21
|
+
autoload :DirtyTime, 'dirty_seed/assigners/dirty_time'
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faker'
|
4
|
+
|
5
|
+
module DirtySeed
|
6
|
+
module Assigners
|
7
|
+
# Draws a value matching validators
|
8
|
+
class DirtyAssigner
|
9
|
+
attr_reader :dirty_attribute, :sequence
|
10
|
+
|
11
|
+
# Initializes an instance
|
12
|
+
# @param attribute [DirtySeed::DirtyAttribute]
|
13
|
+
# @param sequence [Integer]
|
14
|
+
# @return [DirtySeed::Assigners::DirtyAssigner]
|
15
|
+
def initialize(dirty_attribute, sequence)
|
16
|
+
@dirty_attribute = dirty_attribute
|
17
|
+
@sequence = sequence
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns an validators related to the current attribute
|
21
|
+
# @return [Array<ActiveModel::Validations::EachValidators>]
|
22
|
+
def validators
|
23
|
+
dirty_attribute.validators
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a random value depending on the attribute type
|
27
|
+
# @return [void]
|
28
|
+
# @note This method should be overrided
|
29
|
+
def value; end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DirtySeed
|
4
|
+
module Assigners
|
5
|
+
# Draws a boolean value matching validators
|
6
|
+
class DirtyBoolean < DirtyAssigner
|
7
|
+
# Returns a boolean
|
8
|
+
# @return [Boolean]
|
9
|
+
def value
|
10
|
+
[true, false].sample
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DirtySeed
|
4
|
+
module Assigners
|
5
|
+
# Draws a Date matching validators
|
6
|
+
class DirtyDate < DirtyAssigner
|
7
|
+
# Returns a date matching all validators
|
8
|
+
# @return [Date]
|
9
|
+
def value
|
10
|
+
::Faker::Date.between(from: 42.days.ago, to: 42.days.from_now)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DirtySeed
|
4
|
+
module Assigners
|
5
|
+
# Draws an Float matching validators
|
6
|
+
class DirtyFloat < DirtyAssigner
|
7
|
+
# Returns a float matching all validators
|
8
|
+
# @return [Float]
|
9
|
+
def value
|
10
|
+
integer + decimals
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Returns an Integer matching all validators
|
16
|
+
# @return [Integer]
|
17
|
+
def integer
|
18
|
+
DirtySeed::Assigners::DirtyInteger.new(dirty_attribute, 0).value
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a Float between 0 and 1
|
22
|
+
# @return [Float]
|
23
|
+
def decimals
|
24
|
+
rand(0..Float(1))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DirtySeed
|
4
|
+
module Assigners
|
5
|
+
# Draws an integer matching validators
|
6
|
+
class DirtyInteger < DirtyAssigner
|
7
|
+
attr_reader :min, :max
|
8
|
+
|
9
|
+
# Returns an integer matching all validators
|
10
|
+
# @return [Integer]
|
11
|
+
def value
|
12
|
+
define_min_and_max
|
13
|
+
adjust_values
|
14
|
+
rand(min..max)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# Sets @min and @max if not already set
|
20
|
+
# @return [void]
|
21
|
+
def adjust_values
|
22
|
+
return if @min && @max
|
23
|
+
|
24
|
+
if @min
|
25
|
+
@max = @min + random
|
26
|
+
elsif @max
|
27
|
+
@min = @max - random
|
28
|
+
else
|
29
|
+
@min = 0
|
30
|
+
@max = random
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a random integer
|
35
|
+
# @return [Integer]
|
36
|
+
def random
|
37
|
+
rand(sequence..42)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Defines @min and @max based on each validator
|
41
|
+
# @return [void]
|
42
|
+
def define_min_and_max
|
43
|
+
validators.each do |validator|
|
44
|
+
adjust_min!(validator)
|
45
|
+
adjust_max!(validator)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Sets or updates @min so it matches validator
|
50
|
+
# @param validator [ActiveModel::Validations::EachValidator]
|
51
|
+
# @return [Integer, nil]
|
52
|
+
def adjust_min!(validator)
|
53
|
+
return unless min_for(validator)
|
54
|
+
|
55
|
+
@min = min_for(validator) if @min.nil? || min_for(validator) > @min
|
56
|
+
end
|
57
|
+
|
58
|
+
# Sets or updates @max so it matches validator
|
59
|
+
# @param validator [ActiveModel::Validations::EachValidator]
|
60
|
+
# @return [Integer, nil]
|
61
|
+
def adjust_max!(validator)
|
62
|
+
return unless max_for(validator)
|
63
|
+
|
64
|
+
@max = max_for(validator) if @max.nil? || max_for(validator) < @max
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns an integer representing the minimal acceptable value
|
68
|
+
# @param validator [ActiveModel::Validations::EachValidator]
|
69
|
+
# @return [Integer]
|
70
|
+
def min_for(validator)
|
71
|
+
validator.options[:greater_than]&.+(1) ||
|
72
|
+
validator.options[:greater_than_or_equal_to] ||
|
73
|
+
validator.options[:in]&.min
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns an integer representing the maximal acceptable value
|
77
|
+
# @param validator [ActiveModel::Validations::EachValidator]
|
78
|
+
# @return [Integer]
|
79
|
+
def max_for(validator)
|
80
|
+
validator.options[:less_than]&.-(1) ||
|
81
|
+
validator.options[:less_than_or_equal_to] ||
|
82
|
+
validator.options[:in]&.max
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DirtySeed
|
4
|
+
module Assigners
|
5
|
+
# Draws a String matching validators
|
6
|
+
class DirtyString < DirtyAssigner
|
7
|
+
SPECIFIC_ATTRIBUTES = {
|
8
|
+
address: -> { Faker::Address.unique.full_address },
|
9
|
+
city: -> { Faker::Address.unique.city },
|
10
|
+
country: -> { Faker::Address.unique.country },
|
11
|
+
description: -> { Faker::Lorem.unique.paragraph(sentence_count: 2, random_sentences_to_add: 4) },
|
12
|
+
email: -> { Faker::Internet.unique.email(domain: 'example') },
|
13
|
+
first_name: -> { ::Faker::Name.unique.first_name },
|
14
|
+
firstname: -> { ::Faker::Name.unique.first_name },
|
15
|
+
last_name: -> { ::Faker::Name.unique.last_name },
|
16
|
+
lastname: -> { ::Faker::Name.unique.last_name },
|
17
|
+
lat: -> { Faker::Address.unique.latitude },
|
18
|
+
latitutde: -> { Faker::Address.unique.latitude },
|
19
|
+
lng: -> { Faker::Address.unique.longitude },
|
20
|
+
locale: -> { Faker::Address.unique.country_code },
|
21
|
+
longitude: -> { Faker::Address.unique.longitude },
|
22
|
+
middlename: -> { ::Faker::Name.unique.middle_name },
|
23
|
+
middle_name: -> { ::Faker::Name.unique.middle_name },
|
24
|
+
password: -> { ::Faker::Internet.unique.password },
|
25
|
+
phone: -> { Faker::PhoneNumber.unique.phone_number },
|
26
|
+
phone_number: -> { Faker::PhoneNumber.unique.phone_number },
|
27
|
+
reference: -> { Faker::Internet.unique.uuid },
|
28
|
+
title: -> { Faker::Lorem.unique.sentence(word_count: 3, random_words_to_add: 4) },
|
29
|
+
username: -> { Faker::Internet.unique.username }
|
30
|
+
}.freeze
|
31
|
+
private_constant :SPECIFIC_ATTRIBUTES
|
32
|
+
|
33
|
+
# Returns a string matching all validators
|
34
|
+
# @return [String]
|
35
|
+
# @note First try to guess attribute meaning by its name and use Faker to return a coherent value
|
36
|
+
def value
|
37
|
+
SPECIFIC_ATTRIBUTES[dirty_attribute.name]&.call || default
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Returns a standard string
|
43
|
+
# @return [String]
|
44
|
+
def default
|
45
|
+
::Faker::Lorem.unique.sentence(word_count: 3, supplemental: false, random_words_to_add: 4)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DirtySeed
|
4
|
+
module Assigners
|
5
|
+
# Draws a Time matching validators
|
6
|
+
class DirtyTime < DirtyAssigner
|
7
|
+
# Returns a time matching all validators
|
8
|
+
# @return [Time]
|
9
|
+
def value
|
10
|
+
::Faker::Time.between(from: DateTime.now - 42, to: DateTime.now + 42)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DirtySeed
|
4
|
+
# Represents the data model
|
5
|
+
class DataModel
|
6
|
+
include Singleton
|
7
|
+
attr_accessor :logs
|
8
|
+
|
9
|
+
class << self
|
10
|
+
# Defines class methods forwarding to instance methods
|
11
|
+
%i[seed models active_record_models print_logs].each do |method_name|
|
12
|
+
define_method(method_name) { instance.public_send(method_name) }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns dirty model if method_name matches its name
|
16
|
+
# @return [DirtySeed::DirtyModel]
|
17
|
+
# @raise [NoMethodError] if method_name does not match any dirty model
|
18
|
+
def method_missing(method_name, *args, &block)
|
19
|
+
models.find do |model|
|
20
|
+
model.name.underscore.to_sym == method_name
|
21
|
+
end || super
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns true if method_name matches a dirty model name
|
25
|
+
# @return [Boolean]
|
26
|
+
def respond_to_missing?(method_name, include_private = false)
|
27
|
+
models.any? do |model|
|
28
|
+
model.name.underscore.to_sym == method_name
|
29
|
+
end || super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Initializes an instance
|
34
|
+
# @return [DirtySeed::DataModel]
|
35
|
+
def initialize
|
36
|
+
Rails.application.eager_load!
|
37
|
+
@logs = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Seeds the database with dirty instances
|
41
|
+
# @return [void]
|
42
|
+
def seed
|
43
|
+
# check if ApplicationRecord is defined first
|
44
|
+
::ApplicationRecord && 3.times { models.each(&:seed) }
|
45
|
+
print_logs
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns an dirty models
|
49
|
+
# @return [Array<DirtySeed::DirtyModel>]
|
50
|
+
def models
|
51
|
+
@models ||=
|
52
|
+
active_record_models.map do |active_record_model|
|
53
|
+
DirtySeed::DirtyModel.new(active_record_model)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns ApplicationRecord inherited classes sorted by their associations
|
58
|
+
# @return [Array<Class>] a class inheriting from ApplicationRecord
|
59
|
+
def active_record_models
|
60
|
+
@active_record_models ||=
|
61
|
+
DirtySeed::Sorter.new(unsorted_active_record_models).sort!
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns an ApplicationRecord inherited classes
|
65
|
+
# @return [Array<Class>] a class inheriting from ApplicationRecord
|
66
|
+
def unsorted_active_record_models
|
67
|
+
::ApplicationRecord.descendants.reject(&:abstract_class)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Prints logs in the console
|
71
|
+
# @return [void]
|
72
|
+
def print_logs
|
73
|
+
models.sort_by(&:name).each do |model|
|
74
|
+
puts model.name
|
75
|
+
puts " created: #{model.seeded}"
|
76
|
+
puts " errors: #{model.errors.join(', ')}" if model.errors.any?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|