2010-07-16 18 views
6

¿Cómo debo ingresar mis índices de múltiples colores que contienen funciones en schema.rb?Índices funcionales de Rails Postgres

por ejemplo, esto no funciona:

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")

Respuesta

14

El incorporada en el método ActiveRecord para la creación de índices (add_index) no soporta funciones o cualesquiera otras características más avanzadas. En su lugar se puede utilizar execute para crear el índice con SQL:

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

Tenga en cuenta que el uso de execute en migraciones puede ser problemático si no está utilizando el formato de esquema de SQL (config.active_record.schema_format = :sql). Para obtener más información, busque schema_format.

+0

Para hacer esta migración reversible, sólo tiene que añadir a 'down': ' remove_index: temporary_events, nombre: => "temporary_events_campaign_tinfoid_date_messagetype" ' –

5

Pude obtener índices funcionales de las migraciones de Rails (3.1.3) quitando un par de barandillas.

# 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 

que tenía que hacer mis propios nombres de índice, sin embargo:

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 

(Es probable que no necesita comillas alrededor de los nombres de columna de índice a menos que usted está haciendo algo loco como espacios o caracteres extraños que ponen en ellos.)

(que son probablemente muy bien con mensajes de error postgres al intentar deshacer índices inexistentes.)

Cuestiones relacionadas