id順、カラムの並び順でdump

ar_fixturesのrake db:data:dumpやdb:fixtures:dumpではYAMLの出力順は実行されたSQLやテーブルのカラムの並び順とは関係ないので、全部バラバラになってしまって、レコードがたくさんあったり、カラムが多い場合にすごく読みにくいです。いちいち目で探したり、grepしたりはもう嫌なので、id:kiwamuさんの http://d.hatena.ne.jp/kiwamu/20070205/1170668172 のrake db:data:dumpに手を入れてみました。これでレコードはid順、カラムはテーブル定義順に出力されるはずです。

id:kiwamuさんのrakeタスクの

namespace :db do
  namespace :data do
  ・・・
  end
end

の・・・の部分のどこかに以下のコードを入れてください。

    desc "dump data from database for sharing among developers"
    task :dump_ordered => :environment do
      sql = "SELECT * from %s order by id"
      skip_tables = ["schema_info"]
      ActiveRecord::Base.establish_connection
      (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
        i = "00000"
        FileUtils.mkdir_p("#{RAILS_ROOT}/db/data")
        File.open("#{RAILS_ROOT}/db/data/#{table_name}.yml", 'w') do |file|
          data = ActiveRecord::Base.connection.select_all(sql % table_name)

          klass = Class.new(ActiveRecord::Base) do
            set_table_name table_name
          end
          column_names = klass.columns.map(&:name)
          
          column_order_modeule = Module.new do
            def each_with_column_order(*args, &block)
              @column_names.each do |column_name|
                yield(column_name, self[column_name])
              end
            end
              
            def self.extended(obj)
              obj.instance_eval do
                alias :each_without_column_order :each
                alias :each :each_with_column_order
              end
            end
          end
          
          result = data.inject({}) do |hash, record|
            record.instance_variable_set(:@column_names, column_names)
            record.extend(column_order_modeule)
            key = "#{table_name}_#{i.succ!}"
            hash[key] = record
            hash
          end

          result.instance_eval do
            def each_with_order(*args, &block)
              id_to_keys = {}
              self.each_without_order do |key, value|
                id = value['id'].to_i
                id_to_keys[id] = key
              end
              id_to_keys.keys.sort.each do |id|
                key = id_to_keys[id]
                yield(key, self[key])
              end
            end
            alias :each_without_order :each
            alias :each :each_with_order
          end
          file.write result.to_yaml()
        end
      end
      puts('dump finished.')
    end
rake db:data:dump_ordered

でdb/dataにYAMLのファイルをdumpします。