Motivation
Using production-like data in your staging environment could be very useful, especially for debugging intricate production bugs.
The easiest way to achieve this is to use production database backups. But that’s not an option for rather large applications for two reasons:
- production dump can be extremely large, and it just can’t be dumped and restored in a reasonable time;
- you should care about sensitive data (anonymization).
EvilSeed
aims to solve these problems.
Configuration
require 'evil_seed'
EvilSeed.configure do |config|
# First, you should specify +root models+ and their +constraints+ to limit the number of dumped records:
# This is like Forum.where(featured: true).all
config.root('Forum', featured: true) do |root|
# It's possible to remove some associations from dumping with pattern of association path to exclude
#
# Association path is a dot-delimited string of association chain starting from model itself:
# example: "forum.users.questions"
root.exclude(/\btracking_pixels\b/, 'forum.popular_questions')
# It's possible to limit the number of included into dump has_many and has_one records for every association
# Note that belongs_to records for all not excluded associations are always dumped to keep referential integrity.
root.limit_associations_size(100)
# Or for certain association only
root.limit_associations_size(10, 'forum.questions')
end
# Everything you can pass to +where+ method will work as constraints:
config.root('User', 'created_at > ?', Time.current.beginning_of_day - 1.day)
# For some system-wide models you may omit constraints to dump all records
config.root("Role") do |root|
# Exclude everything
root.exclude(/.*/)
end
# Transformations allows you to change dumped data e. g. to hide sensitive information
config.customize("User") do |u|
# Reset password for all users to the same for ease of debugging on developer's machine
u["encrypted_password"] = encrypt("qwerty")
# Reset or mutate other attributes at your convenience
u["metadata"].merge!("foo" => "bar")
u["created_at"] = Time.current
# Please note that there you have only hash of record attributes, not the record itself!
end
# Anonymization is a handy DSL for transformations allowing you to transform model attributes in declarative fashion
# Please note that model setters will NOT be called: results of the blocks will be assigned to
config.anonymize("User") do
name { Faker::Name.name }
email { Faker::Internet.email }
login { |login| "#{login}-test" }
end
Creating the dump
Just call the #dump
method and pass a path where you want your SQL dump file to appear!
require 'evil_seed'
EvilSeed.dump('path/to/new_dump.sql')