web-dev-qa-db-fra.com

rails 3.2 ne peut pas ajouter d'index à create_table dans la méthode de changement

voici ma migration en 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

et voici l'erreur de migration:

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

quelle est la bonne façon de créer un index?

37
linjunhalida

Vous pouvez toujours ajouter un index dans le cadre d'une migration de "modification". Il vous suffit de le faire en dehors de l'appel à 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

Cela crée correctement la table, puis l'index sur une migration "vers le haut" et supprime l'index, puis la table sur une migration "vers le bas".

73
Brandan

donc je le change à l'ancienne, et ça marche. et je pense qu'il y a une nouvelle façon de le faire en utilisant la méthode de changement.

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
4
linjunhalida

Si vous disposez de plusieurs index et que vous ne souhaitez pas répéter plusieurs fois le nom de la table dans des appels add_index individuels, vous pouvez utiliser un bloc change_table qui suit le 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
3
user1792037
    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
2
user3040683

On dirait create_table donne un ActiveRecord::ConnectionAdapters::TableDefinition classe. Cette classe ne contient pas la méthode index. Au lieu, change_table semble donner un ActiveRecord::ConnectionAdapters::Table classe qui inclut cette méthode index.

Si vous souhaitez ajouter un index lors d'une migration create_table, essayez ceci:

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
1
Lee Jarvis