2010-07-16 2 views
6

Как мне ввести многоцветные индексы, которые содержат функции в schema.rb?Rails Функциональные индексы Postgres

, например, это не работает:

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

ответ

14

Встроенный метод ActiveRecord для создания индексов (add_index) не поддерживает функции или какие-либо другие дополнительные функции. Вместо этого вы можете использовать execute для создания индекса с SQL:

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

Обратите внимание, что использование execute в миграции может быть проблематичным, если вы не используете формат SQL схемы (config.active_record.schema_format = :sql). Для получения дополнительной информации, найдите schema_format.

+0

Для того, чтобы эта миграция обратима, просто добавить в 'down': ' remove_index: temporary_events,: имя => "temporary_events_campaign_tinfoid_date_messagetype" ' –

5

Я смог получить функциональные индексы из маршрутов Rails (3.1.3), удалив пару защитных рельсов!

# 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 

я должен был сделать свои собственные имена индексов, хотя:

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 

(Вы, наверное, не нужно в кавычки имена столбцов индекса, если вы делаете что-то безумное, как положить пространства или странные символы в них.)

(вы, вероятно, хорошо с сообщениями Postgres ошибок при попытке откатить несуществующие индексы.)

1

Если вы используете pg_power камень (https://github.com/TMXCredit/pg_power), вы можете сделать это следующим образом:

add_index(:comments, 'dmetaphone(author)', :using => 'gist')