2009-11-05 5 views
24

J'écris un générateur de migration pour un plugin que j'écris et je dois pouvoir trouver les index uniques d'une table afin de pouvoir modifier les index uniques existants pour en faire un index composite unique. J'ai essayé de trouver un moyen d'accéder aux index d'une table avec ActiveRecord. J'ai seulement pu trouver la méthode ActiveRecord :: ConnectionAdapters :: PostgreSQLAdapter :: indexes, mais malheureusement ceci n'est disponible que pour le PosgreSQLAdapter. Je dois être en mesure de soutenir les autres bases de données majeures. J'ai d'abord greffé le fichier schema.rb pour trouver les index, cela a fonctionné au début, mais j'ai vite réalisé que c'était une mauvaise stratégie. Je pensais que si ActiveRecord ne permettait pas de faire cela pour plusieurs adaptateurs de base de données, je pourrais écrire des requêtes spécifiques à l'adaptateur pour extraire les informations d'index d'une table. Si j'ai besoin de recourir à cette méthode, quel serait un bon moyen de déterminer l'adaptateur utilisé?ActiveRecord trouver des index de table existants

Si quelqu'un connaît un moyen d'obtenir ActiveRecord pour lister les informations d'index de table qui serait idéal.

+1

La seule façon que je peux penser à faire de ce droit est maintenant avec l'aide de ActiveRecord :: SchemaDumper.dump Le problème est que ce vide le schéma actuel stdout $ et je ne sais pas comment capturer cela et convertit la sortie en une chaîne. Si je le savais, je serais capable d'utiliser le code de ma première approche de la lecture schema.rb. Quelqu'un sait comment capturer $ stdout pour quelque chose qui a été écrit dans un bloc? Par exemple, cela ne fonctionne pas: schema_str = IO :: open (2) {ActiveRecord :: SchemaDumper.dump} .read –

+0

Je réalise que cette question est ancienne, mais j'ai eu le même problème en essayant de faire en sorte que SchemaDumper un string. J'ai finalement trouvé la réponse, et je l'afficherai au cas où quelqu'un d'autre a ce problème: 'schema_rb_as_string = ActiveRecord :: SchemaDumper.dump (ActiveRecord :: Base.connection, StringIO.new) .string' – MothOnMars

Répondre

54

Cela fonctionne avec MySQL, SQLite3 et Postgres:

ActiveRecord::Base.connection.tables.each do |table| 
    puts ActiveRecord::Base.connection.indexes(table).inspect 
end 

Mais je pense qu'il ne vous donne les index que vous spécifiquement créés.

En outre, pour savoir quel adaptateur est utilisé:

ActiveRecord::Base.connection.class 
+0

fonctionne aussi avec postgres – nikola

+0

Voici le lien: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html#method-i-indexes – Juguang

12

Juste une mise à jour pour l'inspection plus propre. Comme j'avais beaucoup de tables, je trouvais difficile de chercher des trucs spécifiques.

ActiveRecord::Base.connection.tables.each do |table| 
    indexes = ActiveRecord::Base.connection.indexes(table) 
    if indexes.length > 0 
    puts "====> #{table} <====" 
    indexes.each do |ind| 
     puts "----> #{ind.name}" 
    end 
    puts "====> #{table} <====" 
    2.times{ puts ''} 
    end 
end 

Ceci sera de configuration rapide.

+1

Ceci est une excellente réponse. Beaucoup plus propre que la réponse acceptée. – Lorenz

+0

C'était génial, merci! – Aeramor

Questions connexes