在我的schema.rb中,我有以下行:
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
当我在 psql 中运行di
时,我得到:
Schema | Name | Type | Owner | Table
--------+--------------------------------------------------------------+-------+-------+-----------------------
public | index_users_on_email | index | alex | users
但是,如果我在迁移中包含以下之一:
- remove_index :用户,名称::index_users_on_email
- remove_index :用户, 列: :电子邮件
- remove_index :用户, :电子邮件
- 执行"删除索引index_users_on_email"
我收到以下错误:
rake aborted!
An error has occurred, this and all later migrations canceled:
Index name 'index_users_on_email' on table 'users' does not exist
我也发现了这个问题。那么有什么想法吗?
这来得很晚,但我刚刚遇到了类似的事情。在尝试删除索引之前,您是否有可能重命名"电子邮件"列?如果是这样,通过重命名列,索引将被删除。所以顺序必须是:
1) 删除索引2) 重命名列
如果你想按名称删除索引,你可以这样写:
remove_index(:table_name, :name => 'index_name')
您还应该看看这个问题:在 Rails 3.1.0 迁移中remove_index的正确语法是什么?
有点晚了,但我刚刚遇到了同样的问题,所以我写这个答案是希望它能在未来帮助其他人。
最初的提问者遇到的问题导致了解决方案。在 Rails 3.x 中,index_name_for_remove
的实现似乎存在缺陷,因此它有时不接受命名索引。相反,它提出了一个ArgumentError
,声称该指数不存在。
4.x 中,实现了更改,以便正确处理带有索引名称的哈希传递(我认为,我目前没有 Rails 4 应用程序可供测试)。
如果您需要在 Rails 3.x 中处理这个问题,请查看remove index
的来源会导致解决方案 - 使用 remove_index!
方法。 remove_index!
采用两个参数 - 表名和索引名。因此,在原始海报的问题中,此命令应该可以完成这项工作:
remove_index! :users, :index_users_on_email
更新:发布答案后,我注意到原始海报询问的是 Rails 4,因此在某些情况下,index_name_for_remove
未检测到正确的索引名称的实现似乎仍然存在问题。但是,由于索引的名称是已知的,并且我们不需要实际找出名称是什么(这是index_name_for_remove
内部所做的),我们仍然可以使用 remove_index!
方法来删除它。
我的错误:尝试删除我正在删除的列上的索引。
迁移引起了PG::UndefinedObject: ERROR: index "index_candidates_on_job_id_and_email" does not exist
:
class MergeJobAndJobCandidateModels < ActiveRecord::Migration[6.0]
# ...
def down
change_table :candidates do |t|
t.remove :job_id
# ...
end
remove_index :candidates, %i[email job_id]
end
end
错误:我正在删除列并尝试删除索引。Rails/Postgres 将自动删除不再存在的列上的索引,因此我没有理由在迁移中删除此索引。
希望这可以为遇到此错误的其他人节省一点时间。