SeedMigration
Harry's Data Migrations are a way to manage changes to seed data in a rails app in a similar way to how schema migrations are handled.
Intro
A data migration library, similar to rails built-in schema migration. It also auto generates a db/seeds.rb
file, similar to how schema migrations generate the db/schema.rb
file.
Using this auto generated seed file makes it quick and easy to setup new environments, usually development or test.
Installation
Add gem 'seed_migration'
to your Gemfile
:
gem 'seed_migration'
Usage
Install and run the internal migrations
rake seed_migration:install:migrations
rake db:migrate
That will create the table to keep track of data migrations.
Generate a new migration
You can use the generator :
rails g seed_migration AddFoo
A new file will be created under db/data/
using rails migration convention:
db/data/20140407162007_add_foo.rb
You'll need to implement the #up
method and if you need to be able to rollback, the #down
method.
Running the migrations
To run all pending migrations, simply use
rake seed:migrate
If needed, you can run a specific migration:
rake seed:migrate MIGRATION=20140407162007_add_foo.rb
Rollback
Rolling back the last migration is as simple as:
rake seed:rollback
You can rollback more than one migration at the same time:
rake seed:rollback STEPS=3 # rollback last 3 migrations
Or rollback a specific migration:
rake seed:rollback MIGRATION=20140407162007_add_foo.rb
Registering models
By default no models are registered, so running seed migrations won't update the seeds file. You have to manually register the models in the configuration file.
Simply register a model:
SeedMigration.register Product
You can customize the 'seeded' attribute list:
SeedMigration.register User do
exclude :id, :password
end
This will create a seeds.rb
containing all User and Product in the database:
# encoding: UTF-8
# This file is auto-generated from the current content of the database. Instead
# of editing this file, please use the migrations feature of Seed Migration to
# incrementally modify your database, and then regenerate this seed file.
#
# If you need to create the database on another system, you should be using
# db:seed, not running all the migrations from scratch. The latter is a flawed
# and unsustainable approach (the more migrations you'll amass, the slower
# it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Base.transaction do
Product.create("created_at"=>"2014-04-04T15:42:24Z", "id"=>1, "name"=>"foo", "updated_at"=>"2014-04-04T15:42:24Z")
Product.create("created_at"=>"2014-04-04T15:42:24Z", "id"=>2, "name"=>"bar", "updated_at"=>"2014-04-04T15:42:24Z")
# ...
User.create("created_at"=>"2014-04-04T15:42:24Z", "id"=>1, "name"=>"admin", "updated_at"=>"2014-04-04T15:42:24Z")
# ...
end
SeedMigration::Migrator.bootstrap(20140404193326)
Note that seeds.rb
is only generated in development mode. Production data will not be dumped in this process.
Adding seed_migrations to an existing app
If your app already contains seeds, using this gem could cause some issues. Here is the basic process to follow to ensure a smooth transition:
- Clean your local database, and seed it, that can be done with
rake db:reset
- register all the models that were created in the original seeds file
- run
rake seed:migrate
- At this point, your seeds file will be rewritten with all the
create!
statements - Commit/Push the updated seeds file
Deployment notes
It is recommended to add the rake seed:migrate
to your deploy script, so each new data migrations is ran upon new deploys.
You can enable the extend_native_migration_task
option to automatically run rake seed:migrate
after rake db:migrate
.
Example
rails g seed_migration AddADummyProduct
class AddADummyProduct < SeedMigration::Migration
def up
Product.create!({
:asset_path => "valentines-day.jpg",
:title => "Valentine's Day II: the revenge!",
:active => false,
:default => false,
}, :without_protection => true)
end
def down
Product.destroy_all(:title => "Valentine's Day II: the revenge!")
end
end
Configuration
Use an initializer file for configuration.
List of available configurations :
extend_native_migration_task (default=false)
ignore_ids (default=false)
migration_table_name (default='seed_migration_data_migrations')
: Override the table name for the internal model that holds the migrations
example:
# config/initializers/seed_migration.rb
SeedMigration.config do |c|
c.migration_table_name = 'data_migrations'
c.extend_native_migration_task = true
end
SeedMigration.register User do
exclude :id, :password
end
SeedMigration.register Product
Compatibility
At the moment, we rely by default on
ActiveRecord::Base.connection.reset_pk_sequence!
which is pg
only.
If you need to use this gem with another database, use the ignore_ids
configuration.
Runnings tests
RAILS_ENV=test bundle exec rake app:db:reset
bundle exec rspec spec
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request