验证:如何检查特定错误

时间:2011-09-05 17:36:52

标签: ruby-on-rails

我知道如何检查属性是否有错误:

@post.errors[:title].any?

是否可以检查哪个验证失败(例如“唯一性”)?

4 个答案:

答案 0 :(得分:4)

最近我遇到了一个需要同样事情的情况:用户可以从一个表单一次添加/编辑多个记录。

由于在验证时并未将所有记录都写入数据库,因此我无法使用@David的解决方案。为了使事情变得更加复杂,数据库中已经存在的记录可能会变成重复,由唯一性验证器检测到。

TL; DR:您无法检查是否有特定的验证器 ,但您可以检查具体情况错误

我用这个:

# The record has a duplicate value in `my_attribute`, detected by custom code.
if my_attribute_is_not_unique?
  # Check if a previous uniqueness validator has already detected this:
  unless @record.errors.added?(:my_attribute, :taken)
    # No previous `:taken` error or at least a different text.
    @record.errors.add(:my_attribute, :taken) 
  end
end

一些评论:

  • 它可以与I18n一起使用,但你必须像前一个验证器那样为added?提供相同的插值参数。
  • 如果之前的验证程序已编写自定义邮件而非默认邮件(:taken
  • ,则此功能无效

答案 1 :(得分:3)

通过“拍摄”,我认为你的意思是标题已经存在于数据库中。我进一步假设您的Post模型中有以下行:

validates_uniqueness_of :title

就我个人而言,我认为通过检查验证错误来检查标题是否已经被采用将是脆弱的。 @post.errors[:title]将返回["has already been taken"]之类的内容。但是,如果您决定更改错误消息或将应用程序国际化,该怎么办?我认为你最好写一个方法来做测试:

class Post < ActiveRecord::Base
  def title_unique?
    Post.where(:title => self.title).count == 0
  end
end

然后,您可以使用@post.title_unique?测试标题是否唯一。如果已经有一个Rubygem动态地向ActiveRecord模型添加这样的方法,我不会感到惊讶。

答案 2 :(得分:2)

如果您使用的是Rails 5+,则可以使用errors.details。对于早期的Rails版本,请使用backport gem:https://github.com/cowbell/active_model-errors_details

is_duplicate_title = @post.errors.details[:title].any? do |detail|
  detail[:error] == :uniqueness
end

Rails指南:http://guides.rubyonrails.org/active_record_validations.html#working-with-validation-errors-errors-details

答案 3 :(得分:0)

关于专门检查唯一性验证,这对我不起作用:

@post.errors.added?(:title, :taken)

似乎行为已更改,因此还必须传递该值。这有效:

@post.errors.added?(:title, :taken, value: @post.title)

那是使用^的那个,但这些也可以使用:

@post.errors.details[:title].map { |e| e[:error] }.include? :taken
@post.errors.added?(:title, 'has already been taken')

引用#34629#34652