我在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
任何人都知道发生了什么事?
答案 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已经存在”。