简体   繁体   中英

What is the standard way to dump db to yml fixtures in rails?

I've seen some plugins and custom rake tasks to dump the active db to fixtures, but I'm not sure what the prevailing technique is.

Basically, I want the opposite of rake:db:fixtures:load so that I can put basic db information (the admin user account, for one) into svn for when we deploy. I don't want to have to create fixtures manually for things like sample data that would take a long time.

When we deploy I want to be able to just run

rake db:migrate
rake db:fixtures:load

And be off to the races.

What is the best/preferred method for doing this in rails?

EDIT:

So it seems there is no standard way to do an opposite rake task of db:fixtures:load.

I don't want to use migrations, because I want a standard way of doing this for all my projects, and I don't like the idea of putting any more than maybe the admin account in a migration. Second, I've been rethinking the idea of using the fixtures. I've decided on using yaml_db because it uses rake tasks:

rake db:data:dump
rake db:data:load

The data will wind up in a YAML file without distrupting test fixtures (which could be different, now that I think about this more carefully). Also, if a major distribution tool like Heroku is using it, I don't have to worry about support/longevity issues.

I suppose this is closest to "standard" that I will find.

Thanks for all the great responses.

This sounds like you should be using db/seeds.rb, and the related rake db:seed task. These are designed specifically for loading seed data. You can then make calls to YamlDB to load the data and rake db:data:dump_dir to dump all fixtures to a temporary directory and copy them over to your seed data directory as needed.

Note that this does NOT work for dumping fixtures, as the YAML format is different. ar_fixtures noted above does not work with Rails 3 and does not seem to be supported any more. For dumping fixtures, you might want to try something like this in lib/tasks/dump_fixtures.rake:

namespace :db do
  namespace :fixtures do    
    desc 'Create YAML test fixtures from data in an existing database.  
    Defaults to development database.  Specify RAILS_ENV=production on command line to override.'
    task :dump => :environment do
      sql  = "SELECT * FROM %s"
      skip_tables = ["schema_migrations"]
      ActiveRecord::Base.establish_connection(Rails.env)
      (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
        i = "000"
        File.open("#{Rails.root}/test/fixtures/#{table_name}.yml.new", 'w') do |file|
          data = ActiveRecord::Base.connection.select_all(sql % table_name)
          file.write data.inject({}) { |hash, record|
            hash["#{table_name}_#{i.succ!}"] = record
            hash
          }.to_yaml
        end
      end
    end
  end
end

I found this here and modified it slightly for Rails3.

there is no Standard way to do it. Only a standard way to load fixtures:

rake db:fixtures:load

But there are plenty of examples on the internet:

它不使用与db:fixtures完全相同的格式:load会期望,但ar_fixtures使转储和加载数据非常容易。

I think if is the the standard admin information you might be better off to put that in the migrations. fixtures should ideally be used only for testing.

For anyone else just finding this now I've slightly modified the answer from @jpgeek. Include the schema_migration table in the ignore list and order by ID so the output I get is table_name_001 for ID=1

namespace :db do
  namespace :fixtures do    
    desc 'Create YAML test fixtures from data in an existing database.  
    Defaults to development database.  Specify RAILS_ENV=production on command line to override.'
    task :dump => :environment do
      sql  = "SELECT * FROM %s ORDER BY ID"
      skip_tables = ["schema_info", "schema_migrations"]
      ActiveRecord::Base.establish_connection(Rails.env)
      (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
        i = "000"
        File.open("#{Rails.root}/test/fixtures/#{table_name}.yml.new", 'w') do |file|
          data = ActiveRecord::Base.connection.select_all(sql % table_name)
          file.write data.inject({}) { |hash, record|
            hash["#{table_name}_#{i.succ!}"] = record
            hash
          }.to_yaml
        end
      end
    end
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM