The RailsNotes Newsletter 🟥 ISSUE #7

🟥 ISSUE #7 (Split seeds.rb, seedbank gem, 10x faster seeding)

Propagation of your database seeds 🤓

— SPONSOR —

RailsNotesUI ActionMailer Component library

Quickly build emails with ActionMailer, using components like Email::Button.

Built by me (Harrison 👨‍💻), the author of RailsNotes!

Welcome to The RailsNotes Newsletter — Issue #7!

This week we hit 420 subscribers! 🌱😎

This week has been a quiet one — usually, I aim for 1-2 new articles a week, but lately, I’ve been laser-focused on my ActionMailer UI Components.

If you follow me on Twitter (X?), you might have seen my progress updates. Right now I’m building a TailwindUI-esque site to let people browse and copy components.

Here’s a sneak peek 👀 —

This is just a vanilla Ruby on Rails app! No fancy frontend, just some Stimulus controllers + Rouge for code highlighting. I’m getting tons of great ideas for new articles — I’m hoping to start writing again soon!

This week’s newsletter isn’t about Stimulus or code highlighting though — this week we’re talking about database seeding.

For the savvy seeders, this week’s newsletter will show you how to go deeper and do things like split your seeds.rb into different files, and optimize slow seeding.

By default, Rails keeps seeding pretty basic. Lately though, I’ve found it really interesting to dive into seeding and see just how advanced can we get?

Today I’m got some great resources for savvy seeders. Let’s go!

FEATURED ARTICLE —

MidJourney got into a bit of a desert/techno vibe 🏜️🦾 this morning and I just rolled with it. I guess there are lots of databases in an environment… hence…. split environment seeding?

By default, Rails seeding is very limited. All you get is a single seeds.rb file (which suggests that everything should just go in there).

But in many cases, that’s a terrible idea! What if you want to seed your development environment with huge amounts of test data? Or what if you have some seed data that only makes sense to run in production? You’re going to want to split your seeds.rb somehow.

Fortunately, it’s pretty easy to do that! Since seeds.rb is just a Ruby file, we can write simple code to load different files depending on the RAILS_ENV environment variable.

I show you how to do that in this article. It’s really simple to do, and instantly makes your seeding a lot more powerful.

🌐 MORE ARTICLES —

This is a short article linking to a couple of interesting seeding resources. The thing I found most interesting was the Seedbank gem, which lets you build nested seeds like db/seeds/extra/dog.rb. Then you can run them with rails db:seed:extra:dog.

Plus, there’s a second interesting gem (seed_dump), and a basic version of the seed splitting technique that I covered in my article.

If you’re struggling with slow seeds, this will help you speed them up... a lot. I show you how to seed 10x faster by optimizing your SQL INSERT calls (this is part of a longer article I wrote on seeding with the faker gem, which I featured in issue 3 of this newsletter).

By using upsert_all to INSERT all our records in a single transaction, we cut seeding time for 10,000 records down from 7.5 seconds, to 0.8 seconds 🤯.

This is a great StackOverflow thread with a more advanced way to split your seed files. Rather than just splitting based on RAILS_ENV, this method let’s you create arbitrary seed files and then run them with rake db:seed:seed_file_name.

Super handy if you want more control over your seed files, and it’s pretty simple too! Just a short rake task, and you’re good to go.

— ⚒️ HANDY TIP — 

→ Split your seeds.rb by Rails environment

This is the (very) abbreviated version of my seed-splitting article — look how simple it is!

By grabbing the current Rails environment (development, test, production) with the Rails.env variable, we can tell Rails to load the correct seed file for us. Super handy!

# load the correct seeds file for our Rails environment
# need db/seeds/development.rb, test.rb, production.rb
#

# get the current environment
rails_env = "#{Rails.env.downcase}.rb"

# load the right seed file
load(Rails.root.join( 'db', 'seeds', rails_env))