Rails run seeds in specific order (timestamp your seed files)
Many a times when you generate a model and create a seed file for it, you do so by initializing an empty seed file where name is like model_name_seed.rb (At least that’s how I do it!!)
But what if you want to generate seeds that you want to run in a specific order? Then it becomes a bit tricky. While there are multiple ways to achieve it, the easiest approach I feel is to create timestamped seed files.
The biggest advantage of this is that they always run in the order of creation and that’s how rails read them while running.
rails db:seed
Also, another advantage is timestamp prefixed seed files are always ordered in any development IDE or tools.
It’s quite simple and easy to implement =>
# frozen_string_literal: truenamespace :seed do
desc 'Generate an empty seed file, Usage => rake seed:create'
task create: :environment do
seed_path = "db/seeds/#{Time.now.to_i}_seed.rb"
FileUtils.touch(seed_path)
exit
end
end
Let this rake task reside inside `/lib/tasks/seed.rake`
Now every time you generate a model just run
rake seed:create# This would create seed like => db/seeds/1554711746_seed.rb
If you want to generate seed with a specific name, update your rake task to accept arguments from console
namespace :seed do
desc 'Generate an empty seed file, Usage => rake seed:create seed_name'
task create: :environment do
argument = ARGV[1]
argument = "_#{ARGV[1]}" if argument.present?
seed_path = "db/seeds/#{Time.now.to_i}#{argument}_seed.rb"
FileUtils.touch(seed_path)
exit
end
end
Now to create a seed run the command
rake seed:create my_model# This would create seed like => db/seeds/1554711746_my_model_seed.rb
The rake task can further be improved to write default logic to the created seed file as well.