class Shoulda::Matchers::ActiveRecord::ValidateUniquenessOfMatcher
@private
Public Class Methods
new(attribute)
click to toggle source
Calls superclass method
Shoulda::Matchers::ActiveModel::ValidationMatcher::new
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 269 def initialize(attribute) super(attribute) @expected_message = :taken @options = { case_sensitivity_strategy: :sensitive, } @existing_record_created = false @failure_reason = nil @failure_reason_when_negated = nil @attribute_setters = { existing_record: AttributeSetters.new, new_record: AttributeSetters.new, } end
Public Instance Methods
allow_blank()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 308 def allow_blank @options[:allow_blank] = true self end
allow_nil()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 299 def allow_nil @options[:allow_nil] = true self end
case_insensitive()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 289 def case_insensitive @options[:case_sensitivity_strategy] = :insensitive self end
does_not_match?(given_record)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 345 def does_not_match?(given_record) @given_record = given_record @all_records = model.all does_not_match_presence_of_scopes? || does_not_match_scopes_configuration? || does_not_match_uniqueness_without_scopes? || does_not_match_uniqueness_with_case_sensitivity_strategy? || does_not_match_uniqueness_with_scopes? || does_not_match_allow_nil? || does_not_match_allow_blank? ensure Uniqueness::TestModels.remove_all end
expects_to_allow_blank?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 313 def expects_to_allow_blank? @options[:allow_blank] == true end
expects_to_allow_nil?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 304 def expects_to_allow_nil? @options[:allow_nil] == true end
ignoring_case_sensitivity()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 294 def ignoring_case_sensitivity @options[:case_sensitivity_strategy] = :ignore self end
matches?(given_record)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 329 def matches?(given_record) @given_record = given_record @all_records = model.all matches_presence_of_attribute? && matches_presence_of_scopes? && matches_scopes_configuration? && matches_uniqueness_without_scopes? && matches_uniqueness_with_case_sensitivity_strategy? && matches_uniqueness_with_scopes? && matches_allow_nil? && matches_allow_blank? ensure Uniqueness::TestModels.remove_all end
scoped_to(*scopes)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 284 def scoped_to(*scopes) @options[:scopes] = [*scopes].flatten.map(&:to_sym) self end
simple_description()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 317 def simple_description description = "validate that :#{@attribute} is" description << description_for_case_sensitive_qualifier description << ' unique' if @options[:scopes].present? description << " within the scope of #{inspected_expected_scopes}" end description end
Protected Instance Methods
build_allow_or_disallow_value_matcher(args)
click to toggle source
Calls superclass method
Shoulda::Matchers::ActiveModel::ValidationMatcher#build_allow_or_disallow_value_matcher
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 370 def build_allow_or_disallow_value_matcher(args) super.tap do |matcher| matcher.failure_message_preface = method(:failure_message_preface) matcher.attribute_changed_value_message = method(:attribute_changed_value_message) end end
failure_reason()
click to toggle source
Calls superclass method
Shoulda::Matchers::ActiveModel::ValidationMatcher#failure_reason
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 362 def failure_reason @failure_reason || super end
failure_reason_when_negated()
click to toggle source
Calls superclass method
Shoulda::Matchers::ActiveModel::ValidationMatcher#failure_reason_when_negated
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 366 def failure_reason_when_negated @failure_reason_when_negated || super end
Private Instance Methods
actual_sets_of_scopes()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 503 def actual_sets_of_scopes validations.map do |validation| Array.wrap(validation.options[:scope]).map(&:to_sym) end.reject(&:empty?) end
all_scopes_are_booleans?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 850 def all_scopes_are_booleans? @options[:scopes].all? do |scope| @all_records.map(&scope).all? { |s| boolean_value?(s) } end end
arbitrary_non_blank_value()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 579 def arbitrary_non_blank_value non_blank_value = dummy_value_for(@attribute) limit = column_limit_for(@attribute) is_string_value = non_blank_value.is_a?(String) if is_string_value && limit && limit < non_blank_value.length 'x' * limit else non_blank_value end end
attribute_changed_value_message()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 992 def attribute_changed_value_message <<-MESSAGE.strip As indicated in the message above, :#{last_attribute_setter_used_on_new_record.attribute_name} seems to be changing certain values as they are set, and this could have something to do with why this test is failing. If you or something else has overridden the writer method for this attribute to normalize values by changing their case in any way (for instance, ensuring that the attribute is always downcased), then try adding `ignoring_case_sensitivity` onto the end of the uniqueness matcher. Otherwise, you may need to write the test yourself, or do something different altogether. MESSAGE end
attribute_names_under_test()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 913 def attribute_names_under_test [@attribute] + expected_scopes end
attribute_present_on_model?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 628 def attribute_present_on_model? model.method_defined?("#{attribute}=") || model.columns_hash.key?(attribute.to_s) end
attribute_setter_descriptions_for_new_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 1040 def attribute_setter_descriptions_for_new_record attribute_setters_for_new_record.map do |attribute_setter| same_as_existing = ( attribute_setter.value_written == existing_value_written ) description_for_attribute_setter( attribute_setter, same_as_existing: same_as_existing, ) end end
attribute_setter_for_existing_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 904 def attribute_setter_for_existing_record @attribute_setters[:existing_record].last end
attribute_setters_for_new_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 908 def attribute_setters_for_new_record @attribute_setters[:new_record] + [last_attribute_setter_used_on_new_record] end
available_enum_values_for(scope, previous_value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 869 def available_enum_values_for(scope, previous_value) new_record.defined_enums[scope.to_s].reject do |key, _| key == previous_value end end
boolean_value?(value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 856 def boolean_value?(value) [true, false].include?(value) end
build_attribute_setter(record, attribute_name, value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 917 def build_attribute_setter(record, attribute_name, value) Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeSetter. new( matcher_name: :validate_uniqueness_of, object: record, attribute_name: attribute_name, value: value, ignore_interference_by_writer: ignore_interference_by_writer, ) end
build_failure_reason()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 434 def build_failure_reason String.new('Expected the validation ').tap do |failure_reason_string| failure_reason_string << if expected_scopes.empty? 'not to be scoped to anything, ' else "to be scoped to #{inspected_expected_scopes}, " end if actual_sets_of_scopes.any? failure_reason_string << 'but it was scoped to ' failure_reason_string << "#{inspected_actual_scopes} instead." else failure_reason_string << 'but it was not scoped to anything.' end end end
build_new_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 595 def build_new_record @new_record = existing_record.dup attribute_names_under_test.each do |attribute_name| set_attribute_on_new_record!( attribute_name, existing_record.public_send(attribute_name), ) end @new_record end
case_sensitivity_strategy()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 380 def case_sensitivity_strategy @options[:case_sensitivity_strategy] end
column_for(scope)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 940 def column_for(scope) model.columns_hash[scope.to_s] end
column_limit_for(attribute)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 944 def column_limit_for(attribute) column_for(attribute).try(:limit) end
create_existing_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 560 def create_existing_record @given_record.tap do |existing_record| existing_record.save(validate: false) end rescue ::ActiveRecord::StatementInvalid => e raise ExistingRecordInvalid.create(underlying_exception: e) end
defined_as_enum?(scope)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 860 def defined_as_enum?(scope) model.respond_to?(:defined_enums) && new_record.defined_enums[scope.to_s] end
description_for_attribute_setter( attribute_setter, same_as_existing: nil )
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 1007 def description_for_attribute_setter( attribute_setter, same_as_existing: nil ) description = "its :#{attribute_setter.attribute_name} to " if same_as_existing == false description << 'a different value, ' end description << Shoulda::Matchers::Util.inspect_value( attribute_setter.value_written, ) if attribute_setter.attribute_changed_value? description << ' (read back as ' description << Shoulda::Matchers::Util.inspect_value( attribute_setter.value_read, ) description << ')' end if same_as_existing == true description << ' as well' end description end
description_for_case_sensitive_qualifier()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 393 def description_for_case_sensitive_qualifier case case_sensitivity_strategy when :sensitive ' case-sensitively' when :insensitive ' case-insensitively' else '' end end
descriptions_for_attribute_setters_for_new_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 1036 def descriptions_for_attribute_setters_for_new_record attribute_setter_descriptions_for_new_record.to_sentence end
does_not_match_allow_blank?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 532 def does_not_match_allow_blank? expects_to_allow_blank? && ( update_existing_record!('') && (@failure_reason = nil || disallows_value_of('', @expected_message)) ) end
does_not_match_allow_nil?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 516 def does_not_match_allow_nil? expects_to_allow_nil? && ( update_existing_record!(nil) && (@failure_reason = nil || disallows_value_of(nil, @expected_message) ) ) end
does_not_match_presence_of_attribute?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 618 def does_not_match_presence_of_attribute? if attribute_present_on_model? @failure_reason = ":#{attribute} seems to be an attribute on #{model.name}." false else true end end
does_not_match_presence_of_scopes?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 656 def does_not_match_presence_of_scopes? if scopes_missing_on_model.any? true else inspected_scopes = scopes_present_on_model.map(&:inspect) @failure_reason = String.new.tap do |reason| reason << inspected_scopes.to_sentence reason << if inspected_scopes.many? ' seem to be attributes' else ' seems to be an attribute' end reason << " on #{model.name}." end false end end
does_not_match_scopes_configuration?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 452 def does_not_match_scopes_configuration? if scopes_match? @failure_reason = String.new('Expected the validation ').tap do |failure_reason| if expected_scopes.empty? failure_reason << 'to be scoped to nothing, ' failure_reason << 'but it was scoped to ' failure_reason << "#{inspected_actual_scopes} instead." else failure_reason << 'not to be scoped to ' failure_reason << inspected_expected_scopes end end false else true end end
does_not_match_uniqueness_with_case_sensitivity_strategy?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 732 def does_not_match_uniqueness_with_case_sensitivity_strategy? if should_test_case_sensitivity? @failure_reason = nil value = existing_value_read swapcased_value = value.swapcase if case_sensitivity_strategy == :sensitive disallows_value_of(swapcased_value, @expected_message) else if value == swapcased_value raise NonCaseSwappableValueError.create( model: model, attribute: @attribute, value: value, ) end allows_value_of(swapcased_value, @expected_message) end else true end end
does_not_match_uniqueness_with_scopes?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 779 def does_not_match_uniqueness_with_scopes? expected_scopes.any? && !all_scopes_are_booleans? && expected_scopes.any? do |scope| setting_next_value_for(scope) do @failure_reason = nil disallows_value_of(existing_value_read, @expected_message) end end end
does_not_match_uniqueness_without_scopes?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 699 def does_not_match_uniqueness_without_scopes? @failure_reason = nil if existing_value_read.blank? update_existing_record!(arbitrary_non_blank_value) end allows_value_of(existing_value_read, @expected_message) end
dummy_scalar_value_for(column)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 817 def dummy_scalar_value_for(column) Shoulda::Matchers::Util.dummy_value_for(column.type) end
dummy_value_for(scope)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 807 def dummy_value_for(scope) column = column_for(scope) if column.respond_to?(:array) && column.array [dummy_scalar_value_for(column)] else dummy_scalar_value_for(column) end end
existing_and_new_values_are_same?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 1053 def existing_and_new_values_are_same? last_value_set_on_new_record == existing_value_written end
existing_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 539 def existing_record unless defined?(@existing_record) find_or_create_existing_record end @existing_record end
existing_value_read()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 928 def existing_value_read existing_record.public_send(@attribute) end
existing_value_written()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 932 def existing_value_written if attribute_setter_for_existing_record attribute_setter_for_existing_record.value_written else existing_value_read end end
expected_scopes()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 499 def expected_scopes Array.wrap(@options[:scopes]) end
failure_message_preface()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 952 def failure_message_preface # rubocop:disable Metrics/MethodLength String.new.tap do |prefix| if @existing_record_created prefix << "After taking the given #{model.name}" if attribute_setter_for_existing_record prefix << ', setting ' prefix << description_for_attribute_setter( attribute_setter_for_existing_record, ) else prefix << ", whose :#{attribute} is " prefix << "‹#{existing_value_read.inspect}›" end prefix << ', and saving it as the existing record, then' elsif attribute_setter_for_existing_record prefix << "Given an existing #{model.name}," prefix << ' after setting ' prefix << description_for_attribute_setter( attribute_setter_for_existing_record, ) prefix << ', then' else prefix << "Given an existing #{model.name} whose :#{attribute}" prefix << ' is ' prefix << Shoulda::Matchers::Util.inspect_value( existing_value_read, ) prefix << ', after' end prefix << " making a new #{model.name} and setting " prefix << descriptions_for_attribute_setters_for_new_record prefix << ", the matcher expected the new #{model.name} to be" end end
find_existing_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 556 def find_existing_record model.first.presence end
find_or_create_existing_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 547 def find_or_create_existing_record @existing_record = find_existing_record unless @existing_record @existing_record = create_existing_record @existing_record_created = true end end
has_secure_password?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 591 def has_secure_password? Shoulda::Matchers::RailsShim.has_secure_password?(subject, @attribute) end
inspected_actual_scopes()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 480 def inspected_actual_scopes inspected_actual_sets_of_scopes.to_sentence( words_connector: ' and ', last_word_connector: ', and', ) end
inspected_actual_sets_of_scopes()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 487 def inspected_actual_sets_of_scopes inspected_sets_of_scopes = actual_sets_of_scopes.map do |scopes| scopes.map(&:inspect) end if inspected_sets_of_scopes.many? inspected_sets_of_scopes.map { |x| "(#{x.to_sentence})" } else inspected_sets_of_scopes.map(&:to_sentence) end end
inspected_expected_scopes()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 476 def inspected_expected_scopes expected_scopes.map(&:inspect).to_sentence end
last_attribute_setter_used_on_new_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 1057 def last_attribute_setter_used_on_new_record last_submatcher_run.last_attribute_setter_used end
last_value_set_on_new_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 1061 def last_value_set_on_new_record last_submatcher_run.last_value_set end
matches_allow_blank?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 525 def matches_allow_blank? !expects_to_allow_blank? || ( update_existing_record!('') && allows_value_of('', @expected_message) ) end
matches_allow_nil?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 509 def matches_allow_nil? !expects_to_allow_nil? || ( update_existing_record!(nil) && allows_value_of(nil, @expected_message) ) end
matches_presence_of_attribute?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 608 def matches_presence_of_attribute? if attribute_present_on_model? true else @failure_reason = ":#{attribute} does not seem to be an attribute on #{model.name}." false end end
matches_presence_of_scopes?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 633 def matches_presence_of_scopes? if scopes_missing_on_model.none? true else inspected_scopes = scopes_missing_on_model.map(&:inspect) @failure_reason = String.new.tap do |reason| reason << inspected_scopes.to_sentence reason << if inspected_scopes.many? ' do not seem to be attributes' else ' does not seem to be an attribute' end reason << " on #{model.name}." end false end end
matches_scopes_configuration?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 410 def matches_scopes_configuration? if scopes_match? true else @failure_reason = String.new('Expected the validation ').tap do |failure_reason_string| failure_reason_string << if expected_scopes.empty? 'not to be scoped to anything, ' else "to be scoped to #{inspected_expected_scopes}, " end if actual_sets_of_scopes.any? failure_reason_string << 'but it was scoped to ' failure_reason_string << "#{inspected_actual_scopes} instead." else failure_reason_string << 'but it was not scoped to anything.' end end false end end
matches_uniqueness_with_case_sensitivity_strategy?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 709 def matches_uniqueness_with_case_sensitivity_strategy? if should_test_case_sensitivity? value = existing_value_read swapcased_value = value.swapcase if case_sensitivity_strategy == :sensitive if value == swapcased_value raise NonCaseSwappableValueError.create( model: model, attribute: @attribute, value: value, ) end allows_value_of(swapcased_value, @expected_message) else disallows_value_of(swapcased_value, @expected_message) end else true end end
matches_uniqueness_with_scopes?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 769 def matches_uniqueness_with_scopes? expected_scopes.none? || all_scopes_are_booleans? || expected_scopes.all? do |scope| setting_next_value_for(scope) do allows_value_of(existing_value_read, @expected_message) end end end
matches_uniqueness_without_scopes?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 691 def matches_uniqueness_without_scopes? if existing_value_read.blank? update_existing_record!(arbitrary_non_blank_value) end disallows_value_of(existing_value_read, @expected_message) end
model()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 948 def model @given_record.class end
model_class?(model_name)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 763 def model_class?(model_name) model_name.constantize.ancestors.include?(::ActiveRecord::Base) rescue NameError false end
new_record()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 384 def new_record unless defined?(@new_record) build_new_record end @new_record end
Also aliased as: subject
next_scalar_value_for(scope, previous_value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 829 def next_scalar_value_for(scope, previous_value) column = column_for(scope) if column.type == :uuid SecureRandom.uuid elsif defined_as_enum?(scope) available_values = available_enum_values_for(scope, previous_value) available_values.keys.last elsif polymorphic_type_attribute?(scope, previous_value) Uniqueness::TestModels.create(previous_value).to_s elsif previous_value.respond_to?(:next) previous_value.next elsif previous_value.respond_to?(:to_datetime) previous_value.to_datetime.in(60).next elsif boolean_value?(previous_value) !previous_value else previous_value.to_s.next end end
next_value_for(scope, previous_value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 821 def next_value_for(scope, previous_value) if previous_value.is_a?(Array) [next_scalar_value_for(scope, previous_value[0])] else next_scalar_value_for(scope, previous_value) end end
polymorphic_type_attribute?(scope, previous_value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 865 def polymorphic_type_attribute?(scope, previous_value) scope.to_s =~ /_type$/ && model_class?(previous_value) end
scopes_match?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 471 def scopes_match? actual_sets_of_scopes.empty? && expected_scopes.empty? || actual_sets_of_scopes.any? { |scopes| scopes == expected_scopes } end
scopes_missing_on_model()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 685 def scopes_missing_on_model @_scopes_missing_on_model ||= expected_scopes.reject do |scope| model.method_defined?("#{scope}=") end end
scopes_present_on_model()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 679 def scopes_present_on_model @_scopes_present_on_model ||= expected_scopes.select do |scope| model.method_defined?("#{scope}=") end end
set_attribute_on!(record_type, record, attribute_name, value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 875 def set_attribute_on!(record_type, record, attribute_name, value) attribute_setter = build_attribute_setter( record, attribute_name, value, ) attribute_setter.set! @attribute_setters[record_type] << attribute_setter end
set_attribute_on_existing_record!(attribute_name, value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 886 def set_attribute_on_existing_record!(attribute_name, value) set_attribute_on!( :existing_record, existing_record, attribute_name, value, ) end
set_attribute_on_new_record!(attribute_name, value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 895 def set_attribute_on_new_record!(attribute_name, value) set_attribute_on!( :new_record, new_record, attribute_name, value, ) end
setting_next_value_for(scope) { || ... }
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 790 def setting_next_value_for(scope) previous_value = @all_records.map(&scope).compact.max next_value = if previous_value.blank? dummy_value_for(scope) else next_value_for(scope, previous_value) end set_attribute_on_new_record!(scope, next_value) yield ensure set_attribute_on_new_record!(scope, previous_value) end
should_test_case_sensitivity?()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 757 def should_test_case_sensitivity? case_sensitivity_strategy != :ignore && existing_value_read.respond_to?(:swapcase) && !existing_value_read.empty? end
update_existing_record!(value)
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 568 def update_existing_record!(value) if existing_value_read != value set_attribute_on_existing_record!(@attribute, value) # It would be nice if we could ensure that the record was valid, # but that would break users' existing tests existing_record.save(validate: false) end true end
validations()
click to toggle source
# File lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb, line 404 def validations model.validators_on(@attribute).select do |validator| validator.is_a?(::ActiveRecord::Validations::UniquenessValidator) end end