Regenerate YAML Fixtures from DB in Rails
Asked Answered
A

2

5

I am using Rails and my YAML fixtures are corrupted and unusable. I would like to regenerate the YAML fixtures based on the development database.

I am not trying to take all the DB data and turn it into a fixture. What I want is to recreate the standard fixtures that were created initially when the models were first created.

Is there an easy way to do this in Rails 4?

(I saw this page that discusses how to do this [I think] by creating a rake task. However the Q is from 3 years ago and I wonder if a more direct method has been created yet.)

Astound answered 20/8, 2015 at 20:40 Comment(2)
I think you should try using that answer you linked. I really doubt there's any better way to do what you're asking. It's not a normal use case.Muskellunge
Trying…and failing. :/ I am looking at create_fixtures(), but having a trouble figuring out how to use it due to the lack of documentation...Astound
F
12

There is no standard or very elegant way.

I use this snippet when I need to:

File.open("#{Rails.root}/spec/fixtures/users.yml", 'w') do |file|
  data = User.all.to_a.map(&:attributes)
  data.each{|x| x.delete('id')}
  file.write data.to_yaml
end
Fleur answered 20/8, 2015 at 22:46 Comment(1)
This is a very useful answer! (The linked-to answer wasn't working properly for me)Astound
W
1

I wrote rake task for this.

https://gist.github.com/kuboon/55d4d8e862362d30456e7aa7cd6c9cf5

# lib/tasks/db_fixtures_export.rake
namespace 'db:fixtures' do
  desc "generate fixtures from the current database"

  task :export => :environment do
    Rails.application.eager_load!
    models = defined?(AppicationRecord) ? ApplicationRecord.decendants : ActiveRecord::Base.descendants
    models.each do |model|
      puts "exporting: #{model}"

      # Hoge::Fuga -> test/fixtures/hoge/fuga.yml
      filepath = Rails.root.join('test/fixtures', "#{model.name.underscore}.yml")
      FileUtils.mkdir_p filepath.dirname

      filepath.open('w') do |file|
        hash = {}
        model.find_each do |r|
          key = r.try(:name) || "#{filepath.basename('.*')}_#{r.id}"
          hash[key] = r.attributes.except(:password_digest)
        end
        file.write hash.to_yaml
      end
    end
  end
end
Whistle answered 12/5, 2017 at 16:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.