问题:我想向我的POSTGRESQL数据库添加区分大小写的唯一索引。我可以像这样在数据库上手动直接进行操作:
CREATE UNIQUE INDEX participations_uniqueness_one ON participations (event_id, UPPER(email), UPPER(lastname)) WHERE firstname IS NULL;
CREATE UNIQUE INDEX participations_uniqueness_two ON participations (event_id, UPPER(email), UPPER(firstname)) WHERE lastname IS NULL;
CREATE UNIQUE INDEX participations_uniqueness_three ON participations (event_id, UPPER(email)) WHERE firstname IS NULL AND lastname IS NULL;
CREATE UNIQUE INDEX participations_uniqueness_four ON participations (event_id, UPPER(email), UPPER(firstname), UPPER(lastname));
SQL
这在直接在数据库上执行SQL时有效。
我现在想通过ActiveRecord数据库迁移使用相同的代码。我将其作为简单的SQL放在迁移中:
execute <<-SQL
<above statements>
SQL
但是,Rails似乎完全忽略了UPPER(<attribute>)
。对schema.rb
add_index "participations", ["event_id"], name: "participations_uniqueness_four", unique: true, using: :btree
add_index "participations", ["event_id"], name: "participations_uniqueness_one", unique: true, where: "(firstname IS NULL)", using: :btree
add_index "participations", ["event_id"], name: "participations_uniqueness_three", unique: true, where: "((firstname IS NULL) AND (lastname IS NULL))", using: :btree
add_index "participations", ["event_id"], name: "participations_uniqueness_two", unique: true, where: "(lastname IS NULL)", using: :btree
这不是预期的。
如果我删除了UPPER语句,则实际上由于我的测试在RSPEC中失败,索引不区分大小写:
create(:participation, event_id: event.id, email: 'hans@gmail.com', firstname: "john", lastname: nil)
expect { create(:participation, event_id: event2.id, email: 'hans@gmail.com', firstname: "John", lastname: nil) }.not_to raise_error(ActiveRecord::RecordNotUnique)
=>应该通过但失败
对我来说,随着UPPER的删除,似乎无法将上述INDEX创建到ActiveRecord迁移中。这是ActiveRecord的错误还是打算这样?如何解决?我对此主题一无所获。