### Install EvilSeed Gem Source: https://github.com/evilmartians/evil-seed/blob/master/README.md Instructions for adding the EvilSeed gem to your application's Gemfile and installing it using Bundler, or installing it directly as a gem. ```ruby gem 'evil-seed', require: false ``` ```bash $ bundle ``` ```bash $ gem install evil-seed ``` -------------------------------- ### Creating a Database Dump Source: https://github.com/evilmartians/evil-seed/blob/master/README.md Initiates the database dumping process using Evil Seed and specifies the output file path. ```ruby require 'evil_seed' EvilSeed.dump('path/to/new_dump.sql') ``` -------------------------------- ### Launching Standalone Evil Seed Script Source: https://github.com/evilmartians/evil-seed/blob/master/README.md Command to execute a standalone Evil Seed script, specifying the database connection URL via an environment variable. ```sh DATABASE_URL=mysql2://user:pass@host/db ruby path/to/your/script.rb ``` -------------------------------- ### Standalone Evil Seed Usage Source: https://github.com/evilmartians/evil-seed/blob/master/README.md Demonstrates how to use the Evil Seed gem as a standalone application by defining ActiveRecord models, configuring Evil Seed, establishing a database connection, and generating a dump file. ```ruby #!/usr/bin/env ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'activerecord' gem 'evil-seed' gem 'mysql2' end # Describe your database layout with ActiveRecord models. # See http://guides.rubyonrails.org/active_record_basics.html class Category < ActiveRecord::Base has_many :translations, class_name: "Category::Translation" end class Category::Translation < ActiveRecord::Base belongs_to :category, inverse_of: :translations end # Configure evil-seed itself EvilSeed.configure do |config| config.root("Category", "id < ?", 1000) end # Connect to your database. # See http://guides.rubyonrails.org/configuring.html#configuring-a-database) ActiveRecord::Base.establish_connection(ENV.fetch("DATABASE_URL")) # Create dump in dump.sql file in the same directory as this script EvilSeed.dump(File.join(__dir__, "dump.sql").to_s) ``` -------------------------------- ### Evil Seed Configuration Source: https://github.com/evilmartians/evil-seed/blob/master/README.md Configures Evil Seed for database dumping, including setting root models, limits, exclusions, inclusions, transformations, and anonymization rules. ```ruby 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| # You can limit number of records to be dumped root.limit(100) # Specify order for records to be selected for dump root.order(created_at: :desc) # 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', /\Aforum\.parent\b/) # Include back only certain association chains root.include(parent: {questions: %i[answers votes]}) # which is the same as root.include(/\Aforum(\.|parent(\.|questions(\.(answers|votes))?)?)\z/) # You can also specify custom scoping for associations root.include(questions: { answers: :reactions }) do order(created_at: :desc) # Any ActiveRecord query method is allowed end # 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(5, 'forum.questions') root.limit_associations_size(15, 'forum.questions.answers') # or root.limit_associations_size(5, :questions) root.limit_associations_size(15, questions: :answers) # Limit the depth of associations to be dumped from the root level # All traverses through has_many, belongs_to, etc are counted # So forum.subforums.subforums.questions.answers will be 5 levels deep root.limit_deep(10) 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 # You can ignore columns for any model. This is specially useful when working # with encrypted columns. # # This will remove the columns even if the model is not a root node and is # dumped via an association. config.ignore_columns("Profile", :name) # Disable foreign key nullification for records that are not included in the dump # By default, EvilSeed will nullify foreign keys for records that are not included in the dump config.dont_nullify = true # Unscope relations to include soft-deleted records etc # This is useful when you want to include all records, including those that are hidden by default # By default, EvilSeed will abide default scope of models config.unscoped = true # Verbose mode will print out the progress of the dump to the console along with writing the file # By default, verbose mode is off config.verbose = true config.verbose_sql = true end ``` -------------------------------- ### Restore SQL Dump from Ruby Source: https://github.com/evilmartians/evil-seed/blob/master/README.md Executes a plain SQL dump file using ActiveRecord's connection. This is useful for restoring database dumps directly from a Ruby script. ```ruby ActiveRecord::Base.connection.execute(File.read('path/to/new_dump.sql')) ``` -------------------------------- ### Handle PostgreSQL Circular Dependencies Source: https://github.com/evilmartians/evil-seed/blob/master/README.md A detailed procedure for handling circular dependencies in PostgreSQL by making foreign keys deferrable, restoring the dump within a deferred transaction, and then reverting the foreign keys to non-deferrable. ```ruby connection = ActiveRecord::Base.connection # Convert all foreign keys to deferrable to handle circular dependencies transaction do connection.tables.each do |table| connection.foreign_keys(table).each do |fk| connection.execute <<~SQL.squish ALTER TABLE #{connection.quote_table_name(table)} ALTER CONSTRAINT #{connection.quote_table_name(fk.options[:name])} NOT DEFERRABLE SQL end end end # Load the dump connection.transaction do connection.execute("SET CONSTRAINTS ALL DEFERRED") connection.execute(File.read(filepath)) end # Convert all foreign keys back to not deferrable # See https://begriffs.com/posts/2017-08-27-deferrable-sql-constraints.html#reasons-not-to-defer connection.transaction do connection.tables.each do |table| connection.foreign_keys(table).each do |fk| connection.execute <<~SQL.squish ALTER TABLE #{connection.quote_table_name(table)} ALTER CONSTRAINT #{connection.quote_table_name(fk.options[:name])} NOT DEFERRABLE SQL end end end ``` -------------------------------- ### Reset Primary Key Sequences Source: https://github.com/evilmartians/evil-seed/blob/master/README.md Resets the primary key sequences for all tables in the database. This ensures that new records generated after restoration have unique IDs, preventing conflicts with existing data. ```ruby ActiveRecord::Base.connection.tables.each do |table| ActiveRecord::Base.connection.reset_pk_sequence!(table) end ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.