Как получить список всех таблиц, определенных для базы данных, при использовании активной записи?

126

Как мне получить список всех таблиц, определенных для базы данных, при использовании активной записи?

Джей Страмел
источник

Ответы:

259

Звоните ActiveRecord::ConnectionAdapters::SchemaStatements#tables. Этот метод не задокументирован в адаптере MySQL, но задокументирован в адаптере PostgreSQL. SQLite / SQLite3 также имеет реализованный метод, но недокументированный.

>> ActiveRecord::Base.connection.tables
=> ["accounts", "assets", ...]

Смотрите activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb:21, а также реализации здесь:

Франсуа Босолей
источник
2
В список также входит schema_migrationsтаблица. Просто будь в курсе. Спасибо :)
imechemi 07
ActiveRecord :: Base.connection может быть устаревшим? apidock.com/rails/ActiveRecord/Base/connection Я не вижу там перечисленных ActiveRecord :: Base.connection.tables.
barlop
20

Основываясь на двух предыдущих ответах, вы можете:

ActiveRecord::Base.connection.tables.each do |table|
  next if table.match(/\Aschema_migrations\Z/)
  klass = table.singularize.camelize.constantize      
  puts "#{klass.name} has #{klass.count} records"
end

для перечисления каждой модели, которая абстрагирует таблицу, с количеством записей.

Томас Э
источник
1
для однострочных фанатиков (без дополнительной защиты соответствия таблицы регулярных выражений): (ActiveRecord :: Base.connection.tables - ['schema_migrations']). map {| t | "# {t.classify} имеет # {t.classify.constantize.count} записей"}
Саша Кестле
1
Почему вы здесь используете регулярное выражение? Разве "next if table == 'schema_migrations'" не будет работать так же хорошо?
tbreier
12

Обновление для Rails 5.2

Для Rails 5.2 вы также можете использовать, ApplicationRecordчтобы получить имя Arrayвашей таблицы. Так же, как упоминалось imechemi, имейте в виду, что этот метод также будет возвращать ar_internal_metadataи schema_migrationsв этом массиве.

ApplicationRecord.connection.tables
Орасио
источник
1

Кажется, должен быть способ получше, но вот как я решил свою проблему:

Dir["app/models/*.rb"].each do |file_path|
  require file_path # Make sure that the model has been loaded.

  basename  = File.basename(file_path, File.extname(file_path))
  clazz     = basename.camelize.constantize

  clazz.find(:all).each do |rec|
    # Important code here...
  end
end

Этот код предполагает, что вы следуете стандартным соглашениям об именах моделей для классов и файлов исходного кода.

Джей Страмел
источник
2
Он также предполагает, что все в вашем приложении / моделях / является активной моделью записи
localhostdotdev
0

Не знаю об активной записи, но вот простой запрос:

выберите table_name из INFORMATION_SCHEMA.Tables, где TABLE_TYPE = 'BASE TABLE'

Kon
источник