angst
angst

Reputation: 49

Rails 5 Console Query to Count ALL Records in the DB?

Is there a command/query I can run in the rails console to count all records of all models that are in the DB?

(Using Rails 5 and Postgres)

Upvotes: 0

Views: 454

Answers (3)

SteveTurczyn
SteveTurczyn

Reputation: 36860

All active record models are descendants of ApplicationRecord, so you can do...

ApplicationRecord.descendants.map(&:count).inject(:+)

Note that outside production, classes tend to be loaded only when required, so if you're interested in getting the count fort a non-production environment (e.g. development) you would need to modify the configuation to ensure all records are loaded. In config/environment/development.rb set

config.eager_load = true

You can leave it as such but it will slow down your development server startup time. Personally I don't find it a problem but it depends on the size of your application.

Note that... as pointed out by max in the comments, if you do reload! in your console, your ApplicationRecord.descendants will be an empty array.

Upvotes: 1

max
max

Reputation: 101811

This is not a one-liner but this handles non-conventional models where the table name does not match the class name. It uses ApplicationRecord.descents but handles the caveat that its lazy loading:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  # ApplicationRecord.descendants is lazy loading so we must
  # force rails to load all the models
  def self.eager_load_descendants!
    Dir.glob(Rails.root.join('app', 'models', '**', '*.rb')).map do |pn|
      require_dependency pn
    end
  end

  def self.count_all_models
    eager_load_descendants!
    descendants.each_with_object({}) do |model, hash|
      hash[model.model_name.plural] = model.count
    end
  end
end

It returns a hash:

{"users"=>5, "rainbows"=>2, "ponies"=>0}

If you want a total sum you can just do:

irb(main):002:0> {"users"=>5, "rainbows"=>2, "ponies"=>0}.values.sum
=> 7

Upvotes: 0

Gautam
Gautam

Reputation: 1812

You can do this

ActiveRecord::Base.connection.tables.each do |table|
  next if table.classify.safe_constantize.nil?
  count = table.classify.safe_constantize.count
  puts "#{table} -> #{count}"
end

Upvotes: 0

Related Questions