我可以在rails中静默验证validated_uniqueness_of吗?

时间:2014-04-30 00:02:27

标签: ruby-on-rails ruby activerecord

标题拥有一切......

我想要对列进行唯一约束,但如果尝试使用该约束创建记录,则只是失败。

或者......我应该只使用first_or_initialize / first_or_create吗?

2 个答案:

答案 0 :(得分:4)

first_or_create / first_or_initialize适用于您可以使用它返回现有记录/实例而不是创建/实例化新记录/实例。如果那是你想要的行为,那么也许你应该走那条路。


本答案其余部分的简短版本“为什么要编写一个然后被忽略的约束?这听起来很可疑。”

但是既然你说你想让它失败,请考虑以下几点:

如果它会沉默,那么约束的重点是什么?这会隐藏一个问题,你不希望这样。你的app / DB就像,“嘿,伙计,你告诉我总是拒绝这个非独特的废话,但现在你改变了主意?”你使用这些失败使您的数据保持有效并将错误传递给用户,以便他们能够纠正错误。

如果你只需要在某些情况下强制执行唯一性,但在其他情况下可以避免它(这可能很奇怪,但我听说过更奇怪),那么你需要认真考虑这段代码的设计。绝对是最好的,如果你能明确地说,“这应该总是独特,或永远不关心关于独特 - 一个或另一个。”如果这就是您所需要的,那么您将不得不在数据库级别删除任何唯一性约束(因为您无法有条件地忽略这些约束)并使其成为Rails模型级别的条件约束。但如果你走这条路,那就非常小心。如果您的表格中包含非唯一数据,则无法轻松返回,如果需要,您可能会将未来的自我描绘成无效数据的可怕角落。

如果由于非用户提供的数据而导致唯一性约束失败(即您在应用内部创建的记录完全独立于任何类型的用户输入)那么您的代码中存在错误< / strong>并且应该解决这个问题,因为你应该能够在100%的时间内防止你自己代码中的唯一性约束错误。

如果这是一个临时的事情,也许你正在创建一个基于第三方数据源的记录,该数据源已损坏/有bug,但你现在无法修复它或无法控制它,但是你需要你的应用程序继续工作,如果你问一个关于你的情况的更具体的问题可能会有所帮助,因为临时解决方法是他们自己的一个类别。有些是经过精心设计的变通方法或补丁,而有些则会成为可怕的黑客攻击,这会让您的维护时间缩短。

答案 1 :(得分:1)

是的,你应该使用first_or_create 这是一个例子:

Client.where(:first_name => 'Andy').first_or_create(:locked => false)
# => #<Client id: 1, first_name: "Andy", orders_count: 0, locked: false, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">