2006-10-06 [長年日記]

_ [rails] fixtures

DB の値を fixtures に落とすのに ar_fixtures プラグインが便利そうだけど、:limit が切り捨てる方向でしか使われてないので、真似しながら書いてたらプラグインじゃなくなった :)。 lib/tasks/db_fixtures_save.rake として保存しておく。

namespace :db do
  namespace :fixtures do
    desc "Save records to fixtures using current database"
    task :save => :environment do
      limit = ENV["LIMIT"].to_i if ENV["LIMIT"]
      loaded_models = subclasses_of(ActiveRecord::Base)
      Dir.glob("app/models/*.rb").each do |rb|
        File.basename(rb, ".rb").camelize.constantize
      end
      (subclasses_of(ActiveRecord::Base) - loaded_models).each do |model|
        File.open(File.join("test/fixtures", "#{model.table_name}.yml"), "w") do |yml|
          offset = 0
          until (records = model.find(:all, :limit => limit, :offset => offset)).empty?
            hash = {}
            records.each do |record|
              key = "#{model.class_name.underscore}_#{"%05d" % record.id}"
              value = record.attributes
              hash.store(key, value)
            end
            yml.write(hash.to_yaml.sub(/\A---\s*\n?/, ""))
            break unless limit
            offset += limit
          end
        end
      end
    end
  end
end

キーのソートは

puts({"1" => 1, "9" => 9, "10" => 10}.to_yaml(:SortKeys => true))
---
"9": 9
"1": 1
"10": 10

全然効いてない気がするのでとりあえずなしで。LIMIT=1 にすれば id 順に並びますよー。

[]