Dav*_*ave 16 migration ruby-on-rails unique-index validates-uniqueness-of
我的迁移文件中有以下内容
def self.up
create_table :payment_agreements do |t|
t.boolean :automatic, :default => true, :null => false
t.string :payment_trigger_on_order
t.references :supplier
t.references :seller
t.references :product
t.timestamps
end
end
Run Code Online (Sandbox Code Playgroud)
我想确保如果指定了product_id它是唯一的但我也想允许null所以我在我的模型中有以下内容:
validates :product_id,
:uniqueness => true,
:allow_nil => true
Run Code Online (Sandbox Code Playgroud)
工作得很好,但我应该为迁移文件添加一个索引
add_index :payment_agreements, :product_id, :unique => true
Run Code Online (Sandbox Code Playgroud)
显然,当为product_id插入两个空值时,这将抛出异常.我可以简单地省略迁移中的索引,但是我有可能获得两个PaymentAgreements,其中product_id与此处所示相同:并发性和完整性
我的问题是处理这个问题的最佳/最常用方法是什么
zed*_*xff 11
这取决于您的数据库服务器.至于mysql:
UNIQUE索引创建一个约束,使索引中的所有值必须是不同的.如果您尝试添加具有与现有行匹配的键值的新行,则会发生错误.此约束不适用于除BDB存储引擎之外的NULL值.对于其他引擎,UNIQUE索引允许包含NULL的列的多个NULL值.
一些主要数据库系统不允许唯一索引包含多个 NULL:唯一适用于 NULL 以及非 NULL。在数据库级别上有一些方法可以解决这个问题(例如,触发器或计算列;请参阅链接文本)。
您可以在应用程序级别解决此问题,并进行验证以检查唯一性(如果product_id不为空)。
validate :enforce_unique_product_id
def enforce_unique_product_id
if (!self.product_id.nil? &&
PaymentAgreement.exists?(:conditions=>['product_id = ?', self.product_id]))
errors.add_to_base('There is already an agreement with product id " +
self.product_id)
end
end
Run Code Online (Sandbox Code Playgroud)
(更新:正如 zed_0xff 所指出的,MySql 允许在最常用的存储引擎中的 UNIQUE 索引中存在多个 NULL。)
| 归档时间: |
|
| 查看次数: |
13864 次 |
| 最近记录: |