ruby-on-rails – 当验证在另一个表上有条件时,数据库中的唯一性
我在
Uniqueness validation in database when validation has a condition问了一个类似的问题,但是我的要求发生了变化,因此这个问题.
当有多个进程时,在Rails中使用唯一性验证是不安全的,除非在数据库上也强制执行约束(在我的例子中是PostgreSQL数据库,所以参见http://robots.thoughtbot.com/the-perils-of-uniqueness-validations). 在我的例子中,唯一性验证是有条件的:只有在另一个模型上的另一个属性变为真时才应该强制执行.所以我有 class Parent < ActiveRecord::Base # attribute is_published end class Child < ActiveRecord::Base belongs_to :parent validates_uniqueness_of :text,if: :parent_is_published? def parent_is_published? self.parent.is_published end end 所以模型Child有两个属性:parent_id(与Parent关联)和text(文本属性).模型Parent有一个属性:is_published(布尔值).如果其parent.is_published为true,则所有类型为Child的模型的文本应该是唯一的. 使用http://robots.thoughtbot.com/the-perils-of-uniqueness-validations中建议的唯一索引太过限制,因为无论is_published的值如何,它都会强制执行约束. 是否有人知道PostgreSQL数据库上依赖于另一个表的“条件”索引? Uniqueness validation in database when validation has a condition的解决方案是您的条件取决于同一个表中的属性.还是另一种解决方法? 解决方法
不幸的是,没有像
your previous question那样简单和干净的解决方案.
这应该做的工作: >将一个冗余标志is_published添加到Child表中 ALTER TABLE child ADD column is_published boolean NOT NULL; 在插入时将其设置为DEFAULT FALSE或您在父列中通常拥有的任何内容. ALTER TABLE parent ADD CONSTRAINT parent_fk_uni UNIQUE (parent_id,is_published); 由于parent_id是主键,因此组合在任何一种方式都是唯一的.但这是以下fk约束所必需的. ALTER TABLE child ADD CONSTRAINT child_special_fkey FOREIGN KEY (parent_id,is_published) REFERENCES parent (parent_id,is_published) ON UPDATE CASCADE; >然后像上一个答案一样添加partial UNIQUE index. CREATE UNIQUE INDEX child_txt_is_published_idx ON child (text) WHERE is_published; 当然,在子表中插入行时,您必须立即使用parent.is_published的当前状态.但重点是:强制执行参照完整性. 完整的架构 或者,不是调整现有的架构,而是完整的布局: CREATE TABLE parent( parent_id serial PRIMARY KEY,is_published bool NOT NULL DEFAULT FALSE --,more columns ...,UNIQUE (parent_id,is_published) -- required for fk ); CREATE TABLE child ( child_id serial PRIMARY KEY,parent_id integer NOT NULL,is_published bool NOT NULL DEFAULT FALSE,txt text,FOREIGN KEY (parent_id,is_published) REFERENCES parent (parent_id,is_published) ON UPDATE CASCADE ); CREATE UNIQUE INDEX child_txt_is_published_idx ON child (text) WHERE is_published; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |