2010-07-16 4 views
6

Comment entrer mes index multicolum contenant des fonctions dans schema.rb?Rails index fonctionnels de Postgres

par exemple cela ne fonctionne pas:

add_index "temporary_events", ["templateinfoid", "campaign", "date(gw_out_time)", "messagetype"], :name => "temporary_events_campaign_tinfoid_date_messagetype" 

rake db:test:load

rake aborted!

PGError: ERROR: column "date(gw_out_time)" does not exist

: CREATE INDEX "temporary_events_campaign_tinfoid_date_messagetype" ON "temporary_events" ("templateinfoid", "campaign", "date(gw_out_time", "messagetype")

Répondre

14

La méthode ActiveRecord intégré pour la création d'index (add_index) ne prend pas en charge les fonctions ou d'autres fonctions plus avancées. Au lieu de cela, vous pouvez utiliser execute pour créer l'index avec SQL:

execute <<-SQL 
    CREATE INDEX temporary_events_campaign_tinfoid_date_messagetype 
    ON temporary_events(templateinfoid, campaign, date(gw_out_time), messagetype); 
SQL 

Notez que l'utilisation de execute des migrations peut être problématique si vous n'utilisez pas le format de schéma SQL (config.active_record.schema_format = :sql). Pour plus d'informations, recherchez schema_format.

+0

Pour rendre cette migration réversible, il suffit d'ajouter à 'down': ' remove_index: temporary_events,: name => "temporary_events_campaign_tinfoid_date_messagetype" ' –

5

J'ai pu obtenir des index fonctionnels à partir des migrations de Rails (3.1.3) en enlevant quelques garde-corps!

# lib/functional_indexes.rb 
    module ActiveRecord 
    module ConnectionAdapters 
     module SchemaStatements 
     #disable quoting of index columns to allow functional indexes (e.g lower(full_name)) 
     def quoted_columns_for_index(column_names, options = {}) 
      column_names 
     end 

     def index_name_for_remove(table_name, options = {}) 
      index_name = index_name(table_name, options) 

      # disable this error check -- it can't see functional indexes 
      #unless index_name_exists?(table_name, index_name, true) 
      # raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist" 
      #end 

      index_name 
     end 
     end 
    end 
    end 

je devais faire mes propres noms d'index, si:

class AddLowerCaseIndexes < ActiveRecord::Migration 
    def up 
     add_index :people, 'lower(full_name)', :name => "index_people_on_lower_full_name" 
     add_index :people, 'lower(company)', :name => "index_people_on_lower_company" 
    end 

    def down 
     remove_index :people, :name => "index_people_on_lower_full_name" 
     remove_index :people, :name => "index_people_on_lower_company" 
    end 
    end 

(Vous n'avez probablement pas besoin de guillemets autour de vos noms de colonnes d'index, sauf si vous faites quelque chose de fou comme mettre des espaces ou des personnages étranges en eux.)

(vous êtes probablement très bien avec des messages d'erreur postgres lors d'une tentative de rollback index non existants.)

Questions connexes