Проверка: как проверить наличие конкретной ошибки - PullRequest
3 голосов
/ 05 сентября 2011

Я знаю, как проверить атрибут на наличие ошибок:

@post.errors[:title].any?

Можно ли проверить, какая проверка не удалась (например, "уникальность")?

Ответы [ 3 ]

4 голосов
/ 12 января 2015

Недавно я столкнулся с ситуацией, когда мне нужно одно и то же: пользователь может добавлять / редактировать несколько записей одновременно из одной формы.

Поскольку во время проверки не все записи были записаны в базу данных, я не могу использовать решение @ 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? те же параметры интерполяции, что и предыдущий валидатор.1025 * Это не работает, если предыдущий валидатор написал пользовательское сообщение вместо сообщения по умолчанию (:taken)
3 голосов
/ 05 сентября 2011

Под "взятым" я предполагаю, что вы имеете в виду, что заголовок уже существует в базе данных. Я также предполагаю, что у вас есть следующая строка в вашей 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 голосов
/ 16 января 2017

Если вы используете Rails 5+, вы можете использовать errors.details.Для более ранних версий Rails используйте гем backport: 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...