使用rails中的范围一起验证两个字段的唯一性的最佳方法

时间:2012-04-06 09:51:42

标签: validation ruby-on-rails-3.2 unique validates-uniqueness-of

在rails 3.2.3中,我想验证链接模型是否具有两个字段的唯一组合。我有一个测试和验证通过测试,如下所示,但似乎有更好的方法来做到这一点。例如,使用具有唯一性的索引会更好吗?如果是这样,为什么?

# link_test.rb
...
test "cannot create two links with same name and url" do
  Link.create!(:name => 'example', :url => 'http://www.example.com')
  assert_raise(ActiveRecord::RecordInvalid, 'could create two links with same name and url'){Link.create!(:name => 'example', :url => 'http://www.example.com')}
end
...

# link.rb
class Link < ActiveRecord::Base
  ...
  validates :name, :uniqueness => {:scope => :url, :message => 'cannot have two entries with same name and url'}
  ...
end

1 个答案:

答案 0 :(得分:1)

我会同时使用它们。

使用唯一索引的优点是数据库也会强制执行它。例如,如果您有六个应用程序服务器,每个应用程序服务器可能会创建一个新记录,那么保护rails中的唯一性极其难以解决问题。缺点是这很难恢复。

在活动记录中执行此操作的优点是,您可以轻松地调试它,获取干净的异常消息并更有效地将问题传达给用户。缺点是它需要额外的查询,并且更容易受到多线程/多进程类型错误的影响。

当两者都可以与数据库唯一索引的绝对可靠性结合使用时,您将获得活动记录验证的可恢复性。当两个请求在同一时刻命中时,您仍然可以在极少数情况下看到不同的错误,但它会使您的数据与您的约束保持一致。