Posts Seeding Your Database with Rake Tasks
Post
Cancel

Seeding Your Database with Rake Tasks

Rake is a build automation tool written in Ruby. It allows you to automate tasks such as running tests, migrating databases, and more.

Rails uses Rake for running various tasks, like bin/rails db:migrate and bin/rails test.

For more information on Rake, you can check out this Rake tutorial on the official Rails Guides.

By default, Rails uses db/seeds.rb to seed the database. You can run this file with bin/rails db:seed to populate your database with initial data.

Example:

1
2
3
4
5
6
7
8
9
10
# db/seeds.rb

puts "Creating initial data..."

5.times do |i|
  Product.create(
    name: "Product #{i}",
    price: rand(10..100)
  )
end

This approach works well for simple cases, but sometimes you need different data for development and production environments. Custom Rake tasks are perfect for these situations.

Let’s assume our application has products, orders, and customers. We want to seed only products in both development and production environments but seed orders and customers only in the development environment.

Seeding Products

First, we’ll create the logic to seed products in db/seeds.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# db/seeds.rb

def seed_products
  puts "Seeding products..."

  10.times do |i|
    Product.create(
      name: "Product #{i}",
      price: rand(10..100)
    )
  end
end

seed_products

Creating a Custom Rake Task

Next, we create a Rake task to seed orders and customers in development. In the lib/tasks directory, generate a new Rake task:

1
bin/rails g task db custom_seed

This generates a file where we define our custom seeding logic:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# lib/tasks/db_custom_seed.rake

namespace :db do
  desc "Seed custom data for development"
  task custom_seed: :environment do
    seed_customers
    seed_orders
  end
end

private

def seed_customers
  puts "Seeding customers..."

  5.times do |i|
    Customer.create(
      name: "Customer #{i}",
      email: "customer#{i}@example.com"
    )
  end
end

def seed_orders
  puts "Seeding orders..."

  customers = Customer.all

  customers.each do |customer|
    3.times do
      Order.create(
        customer: customer,
        total: rand(50..200)
      )
    end
  end
end

Running the Tasks

To seed the database, you run:

1
bin/rails db:seed

This seeds products. For development data, you run:

1
bin/rails db:custom_seed

This seeds customers and orders.

:sparkling_heart: Key Points:

  • Running bin/rails db:seed only seeds products.
  • Running bin/rails db:custom_seed seeds customers and orders for the development environment.
  • The desc method provides a description visible when you run rake -T or bin/rails.

:warning: Gotchas!

  • bin/rails db:reset will not run custom tasks. To fully reset and seed your database, use bin/rails db:drop db:create db:seed and then bin/rails db:custom_seed.

:tada: Conclusion

Using custom Rake tasks for seeding allows you to tailor your database population to different environments easily. This is particularly useful for maintaining clean and relevant data in development versus production environments.

This post is licensed under CC BY 4.0 by the author.