Project

dirty_seed

0.0
No commit activity in last 3 years
No release in over 3 years
Description of DirtySeed.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

~> 2.14.0
>= 5.0, < 7.0
 Project Readme

DirtySeed

🌱 Populate the database with records matching associations and validations in order to quickly test the application rendering.

Installation

Add this line to your application's Gemfile:

gem 'dirty_seed', '~> 0.2.1'

And then execute:

$ bundle

Usage

Once you've installed the gem, you can use the dedicated task.

To seed dirty data, run:

$ rake dirty_seed:seed

This will create 10 records for each model inheriting from ApplicationRecord.

You can change the number of records to seed by adding a COUNT variable:

$ rake dirty_seed:seed COUNT=42

Instance that cannot be saved are simply ignored.

For each model, the number of created records and the recurrent errors are printed out:

rake dirty_seed:seed COUNT=15

User
  created: 15
Article
  created: 0
  errors: Title should contains the user name and the current date

Database population

For each model inheriting from ApplicationRecord, records are created.

Models are sorted by their dependency to each others (through a belongs_to association) to ensure that some records exist before seeding an instance that requires one.

For instance, given the following models, the order of seeding will be User, Article and Notification:

# app/models/article
class Article
  belongs_to :user
  has_many :notifications, as: :notifiable
end

class User
  has_many :articles
  has_many :notifications, as: :notifiable
end

class Notification
  belongs_to :notifiable, polymorphic: true
end

Value assignment

A value is assigned for each attribute, depending on its type.

Special types like json, jsonb and array are treated.

For instance, given the following schema:

# db/schema.rb
create_table 'things' do |t|
  t.binary 'a_binary'
  t.boolean 'a_boolean'
  t.date 'a_date'
  t.datetime 'a_datetime'
  t.decimal 'a_decimal'
  t.integer 'an_integer'
  t.float 'a_float'
  t.string 'a_string'
  t.text 'a_text'
  t.time 'a_time'
  t.json 'a_json'
  t.text[] 'an_array'
end

...then a dirty seeded thing looks like:

{
  a_binary: '13',
  a_boolean: false,
  a_date: Wed, '02 Dec 2020',
  a_datetime: 'Sun, 08 Nov 2020 03:01:34 UTC +00:00',
  a_decimal: 19.8812490973183,
  an_integer: 6,
  a_float: 28.825997012616263,
  a_string: 'Maxime eum ratione ab quod nihil.',
  a_text: 'Autem non in est dolore.',
  a_time: 'Sat, 01 Jan 2000 09:31:22 UTC +00:00',
  a_json: { 'Autem': 'Dolore', 'Lorem': 'Nihil' },
  an_array: ['Autem', 'Dolore', 'Nihil'],
}

Ignored attributes

Some "special" attributes are not getting a value because:

  • Rails assigns it (STI type...);
  • or the RDBMS (PostgreSQL, SQLite...) assigns it;
  • or it is used in specific cases (authentication...).

These attributes are currently:

  • id
  • created_at
  • updated_at
  • type (for STI)
  • encrypted_password (authentication usage)
  • reset_password_token (authentication usage)
  • reset_password_sent_at (authentication usage)
  • remember_created_at (authentication usage)

Associations

For attributes related to an association, an instance matching the belongs_to is assigned.

Polymorphic associations work too and only an instance of a model that has_one or has_many of this association can be assigned.

For instance, given the following schema:

# schema.rb
create_table :notifications do |t|
  t.references :thing
  t.references :notifiable, polymorphic: true, null: false
  t.references :foo, null: false, foreign_key: { to_table: :things }
end

...and the models:

# app/models/notification.rb
class Notification < ApplicationRecord
  belongs_to :notifiable, polymorphic: true
  belongs_to :thing
  belongs_to :bar, class_name: 'Thing', foreign_key: :foo_id
end

# app/models/user.rb
class User < ApplicationRecord
  has_many :notifications, as: :notifiable
end

...then a dirty seeded notification looks like:

{
  :thing_id => 42,
  :notifiable_type => 'User',
  :notifiable_id => 6,
  :foo_id => 75
}

notification.notifiable.class # User
notification.thing.class # Thing
notification.bar.class # Thing

Validations

For attributes requiring validations, assigned value is adapted.

Currently, the following validations are treated:

  • absence
  • format: { with: regex }
  • inclusion: { in: [x, y] }
  • length: { minimum: x }
  • length: { maximum: x }
  • length: { in: x..y }
  • length: { is: x }
  • numericality: { greater_than: x }
  • numericality: { greater_than_or_equal_to: x }
  • numericality: { lesser_than: x }
  • numericality: { lesser_than_or_equal_to: x }
  • numericality: { in: x..y }
  • uniqueness

Attribute with an enum are treated too.

Custom validations are not inspected.

Meaning detection

Some string attribute meanings are guessed by name: email, first_name, latitude...

Values are then built with the faker gem.

For instance, given the following schema:

# db/schema.rb
create_table "users" do |t|
  t.string "first_name"
  t.string "last_name"
  t.string "address"
  t.string "city"
  t.string "country"
  t.string "email"
  t.string "password"
  t.string "phone"
  t.string "username"
  # ...
end

...then a dirty seeded user looks like:

{
  first_name: 'Emory',
  last_name: 'Franecki',
  address: '843 Schneider Squares, Port Olenmouth, TN 12657',
  city: 'Torpshire',
  country: 'United Arab Emirates',
  email: 'scottie_friesen@example.net',
  password: 'ZkUtNtFg4L',
  phone: '(814) 382-6102 x036',
  username: 'ernestine_rau',
  # ...
}

The current attribute names treated this way are:

  • address
  • city
  • color
  • colour
  • country
  • currency
  • description
  • email
  • first_name
  • firstname
  • last_name
  • lastname
  • lat
  • latitude
  • lng
  • locale
  • longitude
  • middlename
  • middle_name
  • password
  • phone
  • phone_number
  • reference
  • title
  • user_name
  • username
  • uuid

License

The gem is available as open source under the terms of the MIT License.

Next features and improvements

  • Add specs to validate all specific errors rescue.
  • Manage validations on dates and times.
  • Detect more meaningful attributes.
  • Detect more protected attributes (attributes to ignore).
  • Add a configuration system to define how to seed: excluded models, default values, faker method...