是否有可用于所有相关记录的特定属性的验证?

时间:2016-06-22 10:11:55

标签: ruby-on-rails ruby-on-rails-5

我有Question has_many :answers(就像SO)。我还希望每个问题只有1个accepted_answer,所以我只是在:accepted模型中添加了Answer属性,它只是一个布尔值。

现在,为了得到我的问题的接受答案,我已经在我的模型上写了一个方法就是这样做:

  def accepted_answer
    answers.where(accepted: true)
  end

这允许我做question.accepted_answer并且它会像你期望的那样返回一个ActiveRelation对象。

没什么特别的。简单而有效。

但是,我想要确保的是,每个accepted: true问题在任何时候都只能有一个答案。

最好的方法是什么?

我考虑过使用验证器,但是找不到以这种方式处理相关对象的验证器。有一些有比特和有趣的作品,但我不能完全适合所有的作品。例如,presenceabsence以及validates_with一样有趣(但最后一个感觉太重了)。

建议?

1 个答案:

答案 0 :(得分:1)

最有可能的方法是使用after_add回调(示例here),通过update_all将所有现有accepted记录设置为false,并接受最新答案设为true。这一切都取决于你的逻辑。

您还可以使用其他一些回调,例如before_save,before_update等,具有类似的功能,具体取决于您的应用程序细节。

它不会退出验证,但它会有效地维持模型所需的状态。此外,验证的目的是在某些事情无效时警告你,但我想你想要在没有这些失败的情况下保存你的对象,并且只强制执行一个接受的答案。

如果您想在第一个被接受后停止添加答案,请告诉我。在这种情况下,它需要不同的功能。