【问题标题】:My uniqueness validation is not being run. What am I missing?我的唯一性验证没有运行。我错过了什么?
【发布时间】:2016-05-17 17:15:00
【问题描述】:

我创建了一对模型:State 和 Country。它们有几个字段和一个 FK 关系:

+-------+      +---------+
| State +----<>+ Country +
+-------+N .. 1+---------+

成为countrybelongs_to 关联(country_id 列)。

Country 和 State 都有一个内部代码,State 对 (code, country) 有唯一性约束。

当我在控制台中运行这些命令时:

us = Country.find_by_iso_abbr :US
ak = State.find_by iso_abbr: :AK, country: us
State.create(iso_abbr: :ak, country: us, name: 'Foo')

这些行实际上按预期工作。两个表中的iso_abbr 代表我谈到的实际代码字段。

执行时,此代码按预期爆炸 (ActiveRecord::RecordNotUnique)。

但是我想包含一个模型验证器,这样就永远不会通过模型达到数据库级别的爆炸。我尝试的是:

models/country.rb
省略代码替换为省略号,因为它与此问题无关

class Country < ...
    ...
    validates_uniqueness_of :iso_abbr
    ...
end

models/state.rb
省略代码替换为省略号,因为它与此问题无关

class State < ...
    ...
    validates_uniqueness_of :iso_abbr, scope: :country
    ...
end

当再次运行 3 行时,我希望 .create 语句返回一个无效的、未保存的对象(因为验证应该失败)而不是与 ActiveRecord::RecordNotUnique 一起爆炸,因为这种爆炸让我认为没有验证正在执行已执行(或者验证通过了!)。

我的 Rails 版本是 4.2.0。

编辑:确认!验证通过。从我的角度来看,它应该失败。通过在控制台中执行此操作:State.new(iso_abbr: :ak, country: us, name: 'Foo').valid? 我得到true,而我期望false

编辑 2:OTOH 如果我写 Country.create(iso_abbr: :US, name: 'Foo') 验证按预期运行(iso_abbrCountry 模型中是唯一的)并且按预期失败(并且没有例外)。

我在这里错过了什么?

【问题讨论】:

    标签: ruby-on-rails validation activerecord


    【解决方案1】:

    这应该是 OP 中使用的两个符号不同的结果::ak:AK 不会被 Postgres 等数据库视为相同,因为它运行区分大小写的比较。

    【讨论】:

    • 这不是问题的答案。我的问题不是关于异常,而是关于验证通过而不是失败。
    • 但是验证没有通过......由于 RecordNotUnique 导致失败 - 上面的链接/引用来自 Rails API 中的validates_uniqueness_of
    • 没有。如果我在控制台State.new(iso_abbr: 'ak', country: us, name: 'Cucaracha').valid? 中尝试此操作,则验证通过(即返回true)。
    • 那么,在您的数据库中,您的两个符号之间是否存在差异::ak:AK。我使用 Postgres,它区分大小写,因此它不会将 'ak' 和 'AK' 视为相同(基于您在 OP 中存在 :AK 和 :ak 的代码)
    • 我认为你成功了!
    猜你喜欢
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多