Validate all Fixtures

UPDATE: Please have a look at valid_attributes

A enhancement to the validate all models task , adds a db:validate_fixtures, which basically loads the fixtures and then validates all models.


To make this work for RSpec you have to “ln -s PATH_TO/spec/fixtures test/fixtures”.

Output:

-- records - model --
         1x FtpAccount
         2x Movie
Movie: id=2
["Title can't be blank"]
         1x Order
         1x Rating
No Table for: Tableless
         4x User

Task:

#base: http://blog.hasmanythrough.com/2006/8/27/validate-all-your-records
#task: rake db:validate_models
namespace :db do
  def all_models
    #get all active record classes
    Dir.glob(RAILS_ROOT + '/app/models/**/*.rb').each do |file|
      begin
        require file unless file =~ /observer/
      rescue
        #require any possible file dependencies
        if $!.to_s =~ /^uninitialized constant (\w+)$/
          require $1.underscore + '.rb'
          retry
        else
          raise
        end
      end
    end
    klasses = Object.subclasses_of(ActiveRecord::Base)
    #throw out session if it is not stored in db
    klasses.reject! do |klass|
      klass == CGI::Session::ActiveRecordStore::Session && ActionController::Base.session_store.to_s !~ /ActiveRecordStore/
    end
    klasses.select{ |c| c.base_class == c}.sort_by(&:name)
  end

  def validate_models
    #validate them
    puts "-- records - model --"
    all_models.each do |klass|
      begin
        total = klass.count
      rescue
        #tableless, session...
        if $!.to_s =~ /Table .* doesn't exist/im
          puts "No Table for: #{klass}"
          next
        end
        raise
      end
      printf "%10dx %s\n", total, klass.name
      chunk_size = 1000
      (total / chunk_size + 1).times do |i|
        chunk = klass.find(:all, :offset => (i * chunk_size), :limit => chunk_size)
        chunk.reject(&:valid?).each do |record|
          puts "#{record.class}: id=#{record.id}"
          p record.errors.full_messages
          puts
        end rescue nil
      end
    end
  end

  desc "Run model validations on all model records in database"
  task :validate_models => :environment do
    validate_models
  end

  desc "Load and validate fixtures (and other models)"
  task :validate_fixtures do
    RAILS_ENV='test'
    
    Rake::Task[:environment].invoke
    Rake::Task["db:fixtures:load"].invoke
    
    validate_models
  end
end

One thought on “Validate all Fixtures

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s