2010-07-16 67 views
6

我應該如何將包含函數的multicolum索引輸入到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」' – 2017-01-28 07:43:41

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