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)
任何人都知道最近发生了什么?
听起来好像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”。