我有一个非常简单的表
categories(parent_id, title)
我正在尝试设置一个唯一约束,以便两个类别不能具有相同的标题和父级。
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.integer :parent_id
t.string :title, :null => false
end
add_index :categories, [:title, :parent_id], :unique => true
end
end
当parent_id为null时,它不会强制标题的唯一性,这是我们需要的。是否有可能确保标题对根类别也是唯一的?
答案 0 :(得分:3)
您可以为此创建唯一索引:
CREATE UNIQUE INDEX ix_categories_root_title
ON categories (title)
WHERE parent_id IS NULL
晚上睡觉要好于依靠触发器或应用程序级验证:P
答案 1 :(得分:2)
你无法在PostgreSQL中使用UNIQUE constraint:
但是,在此比较中,两个空值不相等。这意味着即使存在唯一约束,也可以在至少一个约束列中存储包含空值的重复行。此行为符合SQL标准,但我们听说其他SQL数据库可能不遵循此规则。
根本问题是x = NULL
对于标准SQL中的所有x
都是false。
您可以使用BEFORE INSERT和BEFORE UPDATE触发器对NULL parent_id
值强制执行它,但ActiveRecord不知道触发器是什么,因此您必须手动维护触发器。或者,您可以在自定义验证中完成所有操作,并希望在没有首先完成模型的情况下不会触及您的数据库。