Introduction

Seed Fu is a gem that provides enhanced database seed functionality for your Rails Application. Seed Fu provides a number of features that make it a significantly better alternative to the built in seeding functionality that Rails offers. For starters, Seed Fu lets you quickly and easily create seed sets that can be different based on which environment you are in. For example, on development you might have a set of development data, and on production you might be populating lookup tables. In addition, Seed Fu is much faster because it skips callbacks.

Installation

To install the seed fu gem, we need to first include it in our Gemfile.

Gemfile:

gem 'seed-fu', "~> 2.3.0"

Next we need to run a bundle install to install the gem.

Terminal Commands:

bundle install

Usage

Lets generate a sample model so that we can play around with Seed Fu's functionality.

Terminal Commands:

rails g model Product name price:decimal{12,2}
rake db:migrate

Now we need to create a few directories. Inside these directories will be our seed files. At a bare minimum you need the db/fixtures directory. You can place your seeds in this directory, however Seed Fu will also let you create environment specific directories. For example, seeds in the db/fixtures/development directory will only get used when running in a development environment, and likewise seeds in db/fixtures/production will only get used when operating in a production Rails environment.

Terminal Commands:

mkdir db/fixtures
mkdir db/fixtures/development
mkdir db/fixtures/production

Now lets create a seed file for our products. Typically in Seed Fu you create one seed file per model. You don't have to however, so feel free to use whatever convention that suits your needs. Create a file in db/fixtures/development called products.rb and add the following code.

db/fixtures/development/products.rb

Product.seed do |s|
  s.id = 1
  s.name = "Banana"
  s.price = 0.29
end

Product.seed do |s|
  s.id = 2
  s.name = "Apple"
  s.price = 0.49
end

Product.seed do |s|
  s.id = 3
  s.name = "Strawberry"
  s.price = 0.10
end

Now lets run the Seed Fu rake task to populate the database.

Terminal Commands:

rake db:seed_fu

Now lets start a rails console so that we can check out the contents of our database.

Terminal Commands:

rails c

We can use pluck to see specific fields easily in the Rails Console. Run the command below and you'll see that the database has been populated.

Rails Console Commands:

Product.pluck("id, name, price")

If you are new to the Rails console, please note that you can type exit to exit the console.

Terser Syntax

Seed Fu also contains a more compact syntax. Open up your products seed file and replace it's contents with the following code.

db/fixtures/development/products.rb:

Product.seed(:id, 
  { id: 1, name: "Banana", price: 0.29 },
  { id: 2, name: "Apple", price: 0.49 },
  { id: 3, name: "Strawberry", price: 0.10 },
  { id: 4, name: "Bag of Blueberries", price: 1.99 },
)

Now run the seed fu rake task again.


rake db:seed_fu

Alternate Identifiers

From the output of the rake task you'll notice that the Bag of Blueberries has been added.

Sometimes we may not want to use the id column as a unique identitifier. For example, maybe we want to use name as the unique identifier. We can easily do so. Replace the contents of the products seed file with the code listed below.

db/fixtures/development/products.rb:

Product.seed(:name, 
  { name: "Banana", price: 0.29 },
  { name: "Apple", price: 0.49 },
  { name: "Strawberry", price: 0.10 },
  { name: "Bag of Blueberries", price: 1.99 },
  { name: "Pear", price: 0.75 },
)

Now if you once again examine the contents of your database in the Rails console, you'll notice that the pear has been added and the other items are seemingly unchanged. Seed Fu will automatically update the other fields for these products. For example if we had changed the price, Seed Fu would have updated the record to reflect this.

Additional Notes

  • You can tell Seed Fu to only seed specific models. Simply append FILTER=[modelname] to the end of the seed fu rake command. For example: rake db:seed_fu FILTER=products.
  • Seed Fu skips callbacks, so if you need to run the callbacks, you can add Product.find_each(&:save) to the end of your seed file (for products, change as appropriately for your models.)
  • If you have a ton of seeds, you might want to disable console output to speed things up a bit more. To do this simply add SeedFu.quiet = true to the top of your seed file.
  • Seed Fu's github page is at https://github.com/mbleigh/seed-fu.

That's it! Thanks for reading!