views:

42

answers:

2

I have a sqlite3 db in a rails app with the following schema

ActiveRecord::Schema.define(:version => 20100816231714) do

  create_table "comments", :force => true do |t|
    t.string   "commenter"
    t.text     "body"
    t.integer  "post_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "posts", :force => true do |t|
    t.string   "name"
    t.string   "title"
    t.text     "content"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "tags", :force => true do |t|
    t.string   "name"
    t.integer  "post_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

I began with a Post :has_many relationship with tags so each tag has a post_id reference.

I now want to change this relationship to a 'has_and_belongs_to_many', I know i have to create the joins table etc.... this isn't a problem and is working

The problem comes in when i try remove the post_id form the tags table. My migration looks like this:

class RemoveFieldsToTags < ActiveRecord::Migration
   def self.up
     remove_column :tags, :post_id
   end

   def self.down
     add_column :tags, :post_id, :references
   end
 end

When I run rake db:migrate and rake db:migrate:up VERSION= Nothing happens when I run rake db:migrate:down VERSION= I get column:

SQLite3::SQLException: duplicate column name: post_id: ALTER TABLE "tags" ADD "post_id" references

Any one know whats going on?

+1  A: 

It sounds as if Rails thinks your DB is up to date (given that nothing happens when you run db:migrate). You can get into this state if you've modified your migration after applying it (common during development).

Have you tried running db:migrate on a fresh db (note this will wipe your database)?

rake db:drop db:create db:migrate
avaynshtok
+1  A: 

Like avaynshtok mentions above, it sounds like rails thinks your migrations are up to date (as in, they have all been applied), but to you they are not (the post_id column is still on the tags table).

A common 'workaround' to deal with this situation without having to wipe your database is commenting out the 'down' method of your migration and running

rake db:migrate:redo

Given the 'down' is commented out, it won't try to add the column again, so it will proceed to reapply the 'up' method, removing your 'post_id' column. You can then remove the comment on the 'down' method and it should all be good.

PS. You might want to look into using a 'has_many :through' type of relationship instead of 'has_and_belongs_to_many' as well.

Marcos Toledo
Cheers for the answer, I began using a has_many :through relationship but decided it added a bit of unnecessary complexity (i am going to simplicity), the official stance on this relationship seems to be 'use when you have want to retain information about the join' eg. the time to relationship is made, the result etc...
wtb
This worked by the way, thanks
wtb