我创建了一对模型:州和国家。他们有几个领域和一个FK关系:
+-------+ +---------+
| State +----<>+ Country +
+-------+N .. 1+---------+
country
belongs_to
关联(country_id
列)。
国家/地区和州都有内部代码,州对(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
)。
但是我想要包含一个模型验证器,因此永远不会通过模型达到数据库级别的爆炸。我试过的是:
模型/ country.rb
省略了用省略号替换的代码,因为它与此问题无关
class Country < ...
...
validates_uniqueness_of :iso_abbr
...
end
模型/ 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_abbr
在Country
模型中本身是唯一的)并且按预期失败(并且没有例外)。
我在这里缺少什么?
答案 0 :(得分:1)
它应该是OP中使用的两个符号不同的结果::ak
和:AK
由于运行区分大小写而不会被像Postgres这样的DB看到相同的结果比较。