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

rog*_*oom 5 ruby migration sqlite ruby-on-rails 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
Run Code Online (Sandbox Code Playgroud)

我开始使用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
Run Code Online (Sandbox Code Playgroud)

当我运行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
Run Code Online (Sandbox Code Playgroud)

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

ava*_*tok 5

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

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

rake db:drop db:create db:migrate
Run Code Online (Sandbox Code Playgroud)


小智 4

就像上面提到的 avaynshtok 一样,听起来 Rails 认为你的迁移是最新的(例如,它们都已应用),但对你来说它们不是(post_id 列仍然在标签表上)。

处理这种情况而无需擦除数据库的常见“解决方法”是注释掉迁移和运行的“down”方法

rake db:migrate:redo
Run Code Online (Sandbox Code Playgroud)

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

附言。您可能还想考虑使用“has_many :through”类型的关系而不是“has_and_belongs_to_many”。