rails 3.2 миграция не может добавить индекс для создания таблицы в методе изменения

вот моя миграция в rails 3.2.2:

class CreateStatistics < ActiveRecord::Migration
  def change
    create_table :statistics do |t|
      t.string :name
      t.integer :item_id
      t.integer :value
      t.text :desc

      t.timestamps
      t.index [:name, :item_id]
    end

  end
end

и вот ошибка миграции:

==  CreateStatistics: migrating ===============================================
-- create_table(:statistics)
ActiveRecord::ConnectionAdapters::TableDefinition
rake aborted!
An error has occurred, all later migrations canceled:

undefined method `index' for #<ActiveRecord::ConnectionAdapters::TableDefinition:0xbd16888>

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

Как правильно создать индекс?

5 ответов


вы все еще можете добавить индекс как часть миграции "изменения". Вам просто нужно сделать это за пределами вызова create_table:

class CreateStatistics < ActiveRecord::Migration
  def change
    create_table :statistics do |t|
      t.string :name
      t.integer :item_id
      t.integer :value
      t.text :desc

      t.timestamps
    end

    add_index :statistics, [:name, :item_id]
  end
end

это правильно создает таблицу, а затем индекс при миграции "вверх" и отбрасывает индекс, а затем таблицу при миграции "вниз".


поэтому я меняю его на старый способ, и он работает. и я думаю, что есть новый способ сделать это, используя метод изменения.

class CreateStatistics < ActiveRecord::Migration
  def up
    create_table :statistics do |t|
      t.string :name
      t.integer :item_id
      t.integer :value
      t.text :desc

      t.timestamps
    end
    add_index :statistics, [:name, :item_id]
  end

  def down
    drop_table :statistics
  end
end

Если у вас несколько индексов и вы не хотите повторять имя таблицы несколько раз в отдельных вызовах add_index, вы можете использовать блок change_table, который следует за create_table.

create_table :user_states do |t|
  t.references :user, :null => false
  t.integer :rank
  t.integer :status_code
end

change_table :user_states do |t|
  t.index [:rank, :status_code]
end

    class CreateTempPfp < ActiveRecord::Migration
      def change
        create_table :temp_ptps do |t|
          t.string :owner
          t.integer :source_id
          t.string :source_type
          t.integer :year
          t.string :pcb_type
          t.float :january
          t.float :february
          t.float :march
          t.float :april
          t.float :may
          t.float :june
          t.float :july
          t.float :august
          t.float :september
          t.float :october
          t.float :november
          t.float :december
          t.float :dollar_per_sqft
          t.float :dollar_per_unit
          t.integer :rp_acc_code
          t.integer :rp_property_id
          t.integer :real_estate_property_id
          t.timestamps
       end
       add_index :temp_ptps, [:source_id, :source_type]
     end
   end

похоже create_table дает ActiveRecord::ConnectionAdapters::TableDefinition класса. Этот класс не содержит метод index. Вместо change_table кажется, дает ActiveRecord::ConnectionAdapters::Table класс, который содержит этот index метод.

если вы хотите добавить индекс во время миграции create_table, попробуйте следующее:

class CreateStatistics < ActiveRecord::Migration
  def self.up
    create_table :statistics do |t|
      t.string :name
      t.integer :item_id
      t.integer :value
      t.text :desc

      t.timestamps
    end

    add_index :statistics, :name
    add_index :statistics, :item_id
  end

  def self.down
    drop_table :statistics
  end
end