80

I want to populate a new feature with dummy data, but don't want to use the db/seeds.rb file as it already has seeds other data irrelevant for this feature.

To run the default seeds.rb file, you run the command rake db:seed.

If I create a file in the db directory called seeds_feature_x.rb, what would the rake command look like to run (only) that file?

Fellow Stranger
  • 32,129
  • 35
  • 168
  • 232
  • I'm interesting with your case, is there any code that you have try? One again, why need another `seed` file? Have you done trying to called another method from `seeds.rb`? Last time I was using `seeds.rb` to called a **Import Feature** from other model – ksugiarto Nov 09 '13 at 04:19
  • If I run seeds.rb it would seed my application with a lot of other data that I'm not in need of. That's the reason I don't want to touch it if possible and have a new seed file. – Fellow Stranger Nov 09 '13 at 04:30
  • You can create a custom rake task that executes individual seed files. I've included an example in my answer below... – zeantsoi Nov 09 '13 at 06:00

3 Answers3

189

Start by creating a separate directory to hold your custom seeds – this example uses db/seeds. Then, create a custom task by adding a rakefile to your lib/tasks directory:

# lib/tasks/custom_seed.rake
namespace :db do
  namespace :seed do
    Dir[Rails.root.join('db', 'seeds', '*.rb')].each do |filename|
      task_name = File.basename(filename, '.rb')
      desc "Seed " + task_name + ", based on the file with the same name in `db/seeds/*.rb`"
      task task_name.to_sym => :environment do
        load(filename) if File.exist?(filename)
      end
    end
  end
end

This rakefile accepts the name of a seed file in the db/seeds directory (excluding the .rb extension), then runs it as it would run seeds.rb. You can execute the rake task by issuing the following from the command line:

rake db:seed:file_name # Name of the file EXCLUDING the .rb extension 

Update: Now it should also list the seed tasks when running rake --tasks or rake -T.

Magne
  • 16,401
  • 10
  • 68
  • 88
zeantsoi
  • 25,857
  • 7
  • 69
  • 61
  • 3
    Excellent! I only had to replace `seed_file` with `filename` (edited). – Fellow Stranger Nov 11 '13 at 10:54
  • 23
    In case anyone's wondering, `intern` is an alias for `to_sym`. – PJSCopeland Jul 07 '14 at 03:44
  • 2
    I am getting "Don't know how to build task 'db:seed:base'". I have done as described, only my seed file is called base.rb – AndroC Dec 26 '15 at 21:43
  • 2
    It runs through all the files, but only tries to load the one you specify. How it does this is not clear, as the input is not passed as an argument and there is no "if filename == your_passed_filename" is there to make it clear. – JosephK Apr 13 '16 at 12:28
  • 3
    This is working fine for me on Ruby 2.2 and Rails 4.2.5. Only make sure you call the file `custom_seed.rake` instead of `custom_seed.rb` (the answer is correct, but I managed to mix this up anyway). – vindia Jun 20 '16 at 10:07
  • 2
    Bit late, but @JosephK I was also struggling to understand how this worked at first, so ran it a few times with a few `puts` statements to debug. Effectively this rake script dynamically creates a task for each *.rb file it finds in the target directory. So if your folder contains `seeds_a.rb`, `seeds_b.rb`, `seeds_c.rb`, then when you call `db:seed:seeds_a` the rake script generates 3 tasks under the `seed` namespace, called `seeds_a`, `seeds_b`, `seeds_c`, each task loading the appropriate file. Since you called the task `seed_a`, only that task (and therefore that file) gets executed. – asibs Mar 18 '17 at 12:13
  • How do you get these to display when listing rake tasks using `rake --tasks` ? – Magne Jun 06 '17 at 14:26
  • I found out. Will edit the answer, so it includes this as well. – Magne Jun 06 '17 at 14:33
  • Note: You can list all tasks (even those without descriptions) with `rake -AT`. – Magne Jun 08 '17 at 13:09
17

I tried out zeantsoi's answer but it didn't give me what I wanted, it did all files in a directory. Hacked away at it and got this.

namespace :db do
  namespace :seed do
    task :single => :environment do
      filename = Dir[File.join(Rails.root, 'db', 'seeds', "#{ENV['SEED']}.seeds.rb")][0]
      puts "Seeding #{filename}..."
      load(filename) if File.exist?(filename)
    end
  end
end

And to use this do the following:

rake db:seed:single SEED=<seed_name_without_.seeds.rb>

This will look in the Rails.root/db/seeds folder for a file name without the .seeds.rb (it adds those for you).

Working example:

rake db:seed:single SEED=my_custom_seed

The above would seed the Rails.root/db/seeds/my_custom_seed.seeds.rb file

Heath N
  • 533
  • 1
  • 5
  • 13
  • 2
    This worked perfectly for me! I also had no dice with zeantsoi's answer. I however removed the .seeds extension. Thanks for your help. – themattkellyshow Aug 24 '15 at 15:03
11

Too complicated! I just wanted a simple task to execute every file under db/seeds directory without passing in any file names.

# lib/tasks/seed.rake
desc "Run all files in db/seeds directory"

namespace :db do
  task seed: :environment do
    Dir[File.join(Rails.root, 'db', 'seeds', '*.rb')].each do |filename|
      puts "seeding - #{filename}. for reals, yo!"
      load(filename)
    end
  end
end
Aaron Henderson
  • 1,840
  • 21
  • 20
  • 2
    This conflicts with the rake task db:seed. I suggest change line 2 to read task seeds: :environment do ... – John Doe Jul 04 '16 at 14:42