remove_column不删除列或在rails中给出任何错误

时间:2010-08-17 00:22:08

标签: ruby-on-rails ruby migration sqlite associations

我在rails应用程序中有一个sqlite3数据库,其中包含以下架构

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

我开始使用Post:has_many与标签的关系,因此每个标签都有一个post_id引用。

我现在想将此关系更改为'has_and_belongs_to_many',我知道我必须创建连接表等....这不是问题而且正在工作

当我尝试从标签表中删除post_id形式时出现问题。我的迁移看起来像这样:

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

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

当我运行rake db:migrate和rake db:migrate:up VERSION =当我运行rake db时没有任何事情发生:migrate:down VERSION =我得到了列:

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

任何人都知道发生了什么事?

3 个答案:

答案 0 :(得分:5)

听起来好像Rails认为你的数据库是最新的(假设你运行db:migrate时没有任何反应)。如果您在应用迁移后修改了迁移(在开发期间很常见),则可以进入此状态。

您是否尝试在新数据库上运行db:migrate(请注意这将擦除您的数据库)?

rake db:drop db:create db:migrate

答案 1 :(得分:4)

就像avaynshtok上面提到的那样,听起来像rails认为你的迁移是最新的(因为它们已经被应用了),但对你来说它们不是(post_id列仍然在标签表上)。

在不必擦除数据库的情况下处理这种情况的常见“解决方法”是评论迁移和运行的“向下”方法

rake db:migrate:redo

鉴于'down'被注释掉,它不会再尝试添加列,因此它会继续重新应用'up'方法,删除你的'post_id'列。然后,您可以删除“向下”方法的注释,它应该都很好。

PS。您可能希望使用'has_many:through'类型的关系而不是'has_and_belongs_to_many'。

答案 2 :(得分:0)

我遇到类似问题,但不得不手动删除数据库,然后运行

  

rake db:create db:migrate


  

rake db:migrate:redo

  

rake db:drop

对我不起作用,因为它一直说“db / test.sqlite3已经存在”。