What is Rake?
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.
Why Use a Custom Rake Task for Seeding?
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.
Custom Seeding Logic
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.
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 runrake -T
orbin/rails
.
Gotchas!
-
bin/rails db:reset
will not run custom tasks. To fully reset and seed your database, usebin/rails db:drop db:create db:seed
and thenbin/rails db:custom_seed
.
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.