【发布时间】:2020-05-03 13:06:10
【问题描述】:
是否可以在 rails 控制台中运行命令/查询来计算数据库中所有模型的所有记录?
(使用 Rails 5 和 Postgres)
【问题讨论】:
标签: ruby-on-rails postgresql activerecord ruby-on-rails-5
是否可以在 rails 控制台中运行命令/查询来计算数据库中所有模型的所有记录?
(使用 Rails 5 和 Postgres)
【问题讨论】:
标签: ruby-on-rails postgresql activerecord ruby-on-rails-5
你可以这样做
ActiveRecord::Base.connection.tables.each do |table|
next if table.classify.safe_constantize.nil?
count = table.classify.safe_constantize.count
puts "#{table} -> #{count}"
end
【讨论】:
所有活动记录模型都是 ApplicationRecord 的后代,所以你可以这样做...
ApplicationRecord.descendants.map(&:count).inject(:+)
请注意,在生产之外,类往往仅在需要时才加载,因此如果您有兴趣在非生产环境(例如开发)中获取计数,则需要修改配置以确保加载所有记录.在config/environment/development.rb设置
config.eager_load = true
您可以保留它,但它会减慢您的开发服务器启动时间。我个人认为这不是问题,但这取决于您的应用程序的大小。
请注意...正如 cmets 中的 max 所指出的,如果您在控制台中执行 reload!,您的 ApplicationRecord.descendants 将是一个空数组。
【讨论】:
ApplicationRecord.descendants 是延迟加载并且只会显示已引用的类。
config.eager_load = true 设置为ApplicationRecord.descendants 依赖于类缓存仍然存在问题。例如,如果您运行reload!。 ApplicationRecord.descendants 突然又空了。
这不是单行的,但它可以处理表名与类名不匹配的非常规模型。它使用 ApplicationRecord.descents 但处理延迟加载的警告:
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
它返回一个哈希:
{"users"=>5, "rainbows"=>2, "ponies"=>0}
如果你想要一个总和,你可以这样做:
irb(main):002:0> {"users"=>5, "rainbows"=>2, "ponies"=>0}.values.sum
=> 7
【讨论】: