Rails/PostgreSQL - 如何验证哪里只能有两个用户ID的组合?
问题描述:
我尝试创建聊天加入表时遇到问题。它有两个user_id,user_id1和user_id2。当user_id1为1且user_id2为2时,我可以获得唯一性验证;用这些确切的属性不能再创建聊天。但是我正在执行一次匹配搜索,所以有时匹配出现在user_id1为2和user_id2为1的地方,这是一个问题。Rails/PostgreSQL - 如何验证哪里只能有两个用户ID的组合?
我一直在搜索这两个数据库级别之间的唯一性约束,我似乎无法找到任何。我认为对于模型级别,我必须创建一个自定义验证,我可以弄清楚,但是有没有办法在数据库级别执行此操作?或者有更好的方法来解决这个问题吗?提前致谢。
TL; DR:
A = 1,B = 2
我需要B = 1,一个约束= 2
答
的usual way要做到这一点是create an index on an expression和使用greatest
and least
函数用于构建忽略列顺序的表达式。在你的情况,你需要一个这样的指标:
create unique index whatever_you_want_to_call_it
on your_table(greatest(user_id1, user_id2), least(user_id1, user_id2))
我不知道有什么方法可以让ActiveRecord的构建这样一个指标,也不会被保存在schema.rb
。解决这些问题的方法是切换到SQL模式并在迁移中手动创建索引。从db/schema.rb
切换到db/structure.sql
,在config/application.rb
更新设置:
config.active_record.schema_format = :sql
,然后在迁移创建索引:
def up
connection.execute(%q{
create unique index whatever_you_want_to_call_it
on your_table(greatest(user_id1, user_id2), least(user_id1, user_id2))
})
end
然后,你可以扔掉你的db/schema.rb
(因为它不再是使用)并开始使用db/structure.sql
来代替。您还需要开始使用不同的rake任务:
-
db:structure:dump
而不是db:schema:dump
-
db:structure:load
,而不是db:schema:load
我认为这应该工作。在你的模型'validates:user_id1,uniqueness:{scope::user_id2}',并且这在你的迁移中't.index [:user_id1,:user_id2],unique:true,name:'index_user_id1_and_user_id2'。迁移应该为您的表添加唯一性约束。 – user3366016
感谢您的快速回复。这就是我现在拥有的。现在它确实增加了对货币对唯一性的约束,但不是对中的组合。正如在那里不能有其他的user_id1:1,user_id2:2对。但仍然可以是user_id1:2,user_id2:1对,这是我试图限制的。 –
没有意识到它只走了1路(idX和idY)也不是相反。你可以在迁移中添加第二个约束吗? 't.index [:user_id2,:user_id1],unique:true,name:'index_user_id2_and_user_id1''那么你会有两个? – user3366016