SeedHelper
===========
SeedHelper provides some simple schem and utilities for supporting incremental seeding of data in Ecto with out requiring a full
teardown/setup to obtain consistent data sets.
# Features
## Track versioned seed sections
Run a seed only if it has not already been applied to current database.
```elixir
require SeedHelper
import SeedHelper
seed({"MySeed", "1"}) do
IO.puts "Seeding database..."
# Write data here.
end
```
## Specify seed dependencies.
Wait until required Seed.Version has been applied before executing block.
```elixir
require SeedHelper
import SeedHelper
requires_seed({"MySeed", "2"}) do
seed({"MySeed", "1"}) do
IO.puts "Seeding database... 1"
end
end
# Seed 1 will be queued into an agent until {"MySeed"",2} has executed.
seed({"MySeed", "2"}) do
IO.puts "Seeding database... 2"
end
```
## Specify environment dependencies.
Only apply seeds in test environments, prod, dev, etc.
```elixir
require SeedHelper
import SeedHelper
if_env([:prod,:stage]) do
IO.puts "Running in production or staging environment"
seed({"MySeed", "1"}) do
IO.puts "Seeding database... 1"
end
end
if_env(:test) do
IO.puts "Running in test environment"
requires_seed({"MySeed", "Core"}) do
seed({"MySeed", "test-data"}) do
IO.puts "Seeding database... test-data"
end
end
end
seed({"MySeed", "stuff"}) do
IO.puts "Seeding database... stuff"
if_env(:test) do
IO.puts "Test Specific Stuff"
end
end
```
## Set and Lookup handles
This is useful when inserted data used generated ids but needs to be referenced by other seeds.
handles are stored to the SeedHelper.Schema.Handles (seed_helpers_handles) table
but loaded/fetched during session from an etc cache to avoid perf issues with large data sets/frequent look ups.
```elixir
require SeedHelper
import SeedHelper
seed({"MySeed", "core"}) do
IO.puts "Seeding database... core"
# Save some record with dynamic id.
set_handle("record.id", record.id)
end
# .
# .
# .
seed({"MySeed", "links"}) do
record_id = get_handle("record.id", :or_apple_if_nil)
# Save record referencing record_id
end
```
# Setup
1. Add SeedHelper to your mix.exs file.
```elixir
defp deps do
[
{:seed_helper, "~> 0.1.0"}
]
end
```
2. Set config.exs set repo for seed helper.
```elixir
config :seed_helper, repo: MyApp.Repo
```
3. Setup migration
Run:
```
mix ecto.gen.migration setup_seed_helper
```
# Edit migration file:
```
defmodule MyApp.Repo.Migrations.SetupSeedHelper do
use Ecto.Migration
def up() do
SeedHelper.Migration.up(1)
end
def down() do
SeedHelper.Migration.down(1)
end
end
```
4. Start SeedHelper session in your priv/repo/seeds.exs file
```
require SeedHelper
import SeedHelper
# Begin SeedSession (Agent for requires_seed blocks and etc table for handle cache
begin_session()
dir = Path.dirname(__ENV__.file)
Code.eval_file("#{dir}/seeds/#{Mix.env}-seeds.exs")
# Will throw if and requires_seeds blocks were not resolved during execution.
:ok = end_session()
```