<commit_before>module NoBrainer::Document::Validation
  extend ActiveSupport::Concern
  include ActiveModel::Validations
  include ActiveModel::Validations::Callbacks

  def save(options={})
    options = options.reverse_merge(:validate => true)

    if options[:validate]
      valid? ? super : false
    else
      super
    end
  end

  # TODO Test that thing
  def valid?(context=nil)
    super(context || (new_record? ? :create : :update))
  end

  [:save, :update_attributes].each do |method|
    class_eval <<-RUBY, __FILE__, __LINE__ + 1
      def #{method}!(*args)
        #{method}(*args) or raise NoBrainer::Error::DocumentInvalid, errors
      end
    RUBY
  end

  class UniquenessValidator < ActiveModel::EachValidator
    # Validate the document for uniqueness violations.
    #
    # @example Validate the document.
    #   validate_each(person, :title, "Sir")
    #
    # @param [ Document ] document The document to validate.
    # @param [ Symbol ] attribute The field to validate on.
    # @param [ Object ] value The value of the field.
    #
    # @return [ Boolean ] true if the attribute is unique.
    def validate_each(document, attribute, value)
      is_unique = document.class.where(attribute => value).count == 0
      unless is_unique
        document.errors.add(attribute, 'is already taken')
      end
      is_unique
    end
  end
end<commit_msg>Stop uniqueness validations failing on persisted documents<commit_after>module NoBrainer::Document::Validation
  extend ActiveSupport::Concern
  include ActiveModel::Validations
  include ActiveModel::Validations::Callbacks

  def save(options={})
    options = options.reverse_merge(:validate => true)

    if options[:validate]
      valid? ? super : false
    else
      super
    end
  end

  # TODO Test that thing
  def valid?(context=nil)
    super(context || (new_record? ? :create : :update))
  end

  [:save, :update_attributes].each do |method|
    class_eval <<-RUBY, __FILE__, __LINE__ + 1
      def #{method}!(*args)
        #{method}(*args) or raise NoBrainer::Error::DocumentInvalid, errors
      end
    RUBY
  end

  class UniquenessValidator < ActiveModel::EachValidator
    # Validate the document for uniqueness violations.
    #
    # @example Validate the document.
    #   validate_each(person, :title, "Sir")
    #
    # @param [ Document ] document The document to validate.
    # @param [ Symbol ] attribute The field to validate on.
    # @param [ Object ] value The value of the field.
    #
    # @return [ Boolean ] true if the attribute is unique.
    def validate_each(document, attribute, value)
      finder = document.class.where(attribute => value)
      if document.persisted?
        finder = finder.where{|doc| doc["id"].ne(document.id)}
      end
      is_unique = finder.count == 0
      unless is_unique
        document.errors.add(attribute, 'is already taken')
      end
      is_unique
    end
  end
end
{'fraction_non_alphanumeric': 0.10208262205530898, 'fraction_numerical': 0.0013656538067599864, 'mean_word_length': 3.1093969144460027, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3208060', 'n_tokens_mistral': 852, 'n_tokens_neox': 830, 'n_words': 249}