7

I have one table called profiles with some columns.

Now I wish to add a few columns to this table using the change-method in rails 3.1. I created a migration with the following code:

def change
  change_table :profiles do |t|
    t.string :photo
    t.string :name
    t.references :user
  end
end

The migration works perfectly, but when I want to rollback I get

SQLite3::SQLException: duplicate column name: photo: ALTER TABLE "profiles" ADD "photo" varchar(255)

Any ideas why?

martnu
  • 773
  • 4
  • 11

2 Answers2

6

The auto-generated migrations for adding columns in Rails 3.1 is in the format:

class AddColumnToTable < ActiveRecord::Migration
  def change
    add_column :table, :column, :type
  end
end

Perhaps try that syntax?

sevenseacat
  • 24,699
  • 6
  • 63
  • 88
  • What about adding a reference with add_column? I guess I could do it like this: http://stackoverflow.com/questions/493777/add-column-for-references-rails/493802#493802 But it would be more flexible to be able to add it directly in the migration somehow. – martnu Jul 20 '11 at 11:21
  • @martnu: Adding a reference just adds an ID field of type integer to the table - you could replicate it with `add_column :profiles, :user_id, :integer`. – sevenseacat Jul 20 '11 at 11:49
  • `reference` also adds an index on the `assoc_id` column, which is useful. – Jeriko Jan 30 '12 at 17:23
  • According to the source, no such index is automatically added. You can certainly add one manually, of course. – Binary Phile Aug 26 '12 at 04:39
1

It looks like you need to tell the migration how to revert itself:

def change
  change_table :profiles do |t|
    t.string :photo
    t.string :name
    t.references :user
  end

  reversible do |dir|
    dir.down do
      remove_column :profiles, :photo
      remove_column :profiles, :name
      remove_column :profiles, :user_id
    end
  end
end

See http://guides.rubyonrails.org/migrations.html#using-reversible for more information.

Alternatively you could try using the old up and down methods which are still available like so:

def up
  change_table :profiles do |t|
    t.string :photo
    t.string :name
    t.references :user
  end
end

def down
  remove_column :profiles, :photo
  remove_column :profiles, :name
  remove_column :profiles, :user_id
end

More on up/down here: http://guides.rubyonrails.org/migrations.html#using-the-up-down-methods

Matt Beedle
  • 171
  • 1
  • 9