class Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher
@private
Public Class Methods
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 137 def initialize(attribute) super @expected_message = :blank end
Calls superclass method
Shoulda::Matchers::ActiveModel::Qualifiers::AllowNil::new
Public Instance Methods
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 161 def does_not_match?(subject) super(subject) possibly_ignore_interference_by_writer if secure_password_being_validated? ignore_interference_by_writer.default_to(when: :blank?) disallowed_values.any? do |value| allows_and_double_checks_value_of!(value) end else (expects_to_allow_nil? && disallows_value_of(nil)) || disallowed_values.any? do |value| allows_original_or_typecast_value?(value) end end end
Calls superclass method
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 184 def failure_message message = super if should_add_footnote_about_belongs_to? message << "\n\n" message << Shoulda::Matchers.word_wrap(<<-MESSAGE.strip, indent: 2) You're getting this error because #{reason_for_existing_presence_validation}. *This* presence validation doesn't use "can't be blank", the usual validation message, but "must exist" instead. With that said, did you know that the `belong_to` matcher can test this validation for you? Instead of using `validate_presence_of`, try #{suggestions_for_belongs_to} MESSAGE end message end
Calls superclass method
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 142 def matches?(subject) super(subject) possibly_ignore_interference_by_writer if secure_password_being_validated? && Shoulda::Matchers::RailsShim.active_model_lt_7? ignore_interference_by_writer.default_to(when: :blank?) disallowed_values.all? do |value| disallows_and_double_checks_value_of!(value) end else (!expects_to_allow_nil? || allows_value_of(nil)) && disallowed_values.all? do |value| disallows_original_or_typecast_value?(value) end end end
Calls superclass method
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 180 def simple_description "validate that :#{@attribute} cannot be empty/falsy" end
Private Instance Methods
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 216 def allows_and_double_checks_value_of!(value) allows_value_of(value, @expected_message) rescue ActiveModel::AllowValueMatcher::AttributeChangedValueError raise ActiveModel::CouldNotSetPasswordError.create(model) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 222 def allows_original_or_typecast_value?(value) allows_value_of(value, @expected_message) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 325 def association? association_reflection.present? end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 341 def association_name association_reflection.name end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 345 def association_options association_reflection&.options end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 349 def association_reflection model.try(:reflect_on_association, @attribute) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 335 def attachment? model_has_associations?( ["#{@attribute}_attachment", "#{@attribute}_attachments"], ) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 314 def attribute_accepts_string_values? if association? false elsif attribute_serialization_coder.respond_to?(:object_class) attribute_serialization_coder.object_class == String else RailsShim.supports_full_attributes_api?(model) && attribute_type.try(:type) == :string end end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 359 def attribute_serialization_coder RailsShim.attribute_serialization_coder_for(model, @attribute) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 363 def attribute_type RailsShim.attribute_type_for(model, @attribute) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 310 def belongs_to_association_being_validated? association? && association_reflection.macro == :belongs_to end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 305 def belongs_to_association_configured_to_be_required? association_options[:optional] == false || association_options[:required] == true end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 329 def collection_association? association? && [:has_many, :has_and_belongs_to_many].include?( association_reflection.macro, ) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 236 def disallowed_values if collection_association? [Array.new] elsif attachment? [nil] else values = [] if attribute_accepts_string_values? values << '' end if !expects_to_allow_nil? values << nil end values end end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 226 def disallows_and_double_checks_value_of!(value) disallows_value_of(value, @expected_message) rescue ActiveModel::AllowValueMatcher::AttributeChangedValueError raise ActiveModel::CouldNotSetPasswordError.create(model) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 232 def disallows_original_or_typecast_value?(value) disallows_value_of(value, @expected_message) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 289 def example_of_belongs_to(with: nil) initial_call = "should belong_to(:#{association_name})" inside = if with "#{initial_call}.#{with.first}(#{with.second})" else initial_call end if Shoulda::Matchers.integrations.test_frameworks.any?(&:n_unit?) inside else "it { #{inside} }" end end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 371 def model @subject.class end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 353 def model_has_associations?(associations) associations.any? do |association| !!model.try(:reflect_on_association, association) end end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 210 def possibly_ignore_interference_by_writer if secure_password_being_validated? && RailsShim.active_model_lt_7? ignore_interference_by_writer.default_to(when: :blank?) end end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 367 def presence_validation_exists_on_attribute? model._validators.include?(@attribute) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 261 def reason_for_existing_presence_validation if belongs_to_association_configured_to_be_required? "you've instructed your `belongs_to` association to add a "\ 'presence validation to the attribute' else # assume ::ActiveRecord::Base.belongs_to_required_by_default == true 'ActiveRecord is configured to add a presence validation to all '\ '`belongs_to` associations, and this includes yours' end end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 205 def secure_password_being_validated? Shoulda::Matchers::RailsShim.digestible_attributes_in(@subject). include?(@attribute) end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 256 def should_add_footnote_about_belongs_to? belongs_to_association_being_validated? && presence_validation_exists_on_attribute? end
Source
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 272 def suggestions_for_belongs_to if belongs_to_association_configured_to_be_required? <<~MESSAGE one of the following instead, depending on your use case: #{example_of_belongs_to(with: [:optional, false])} #{example_of_belongs_to(with: [:required, true])} MESSAGE else <<~MESSAGE the following instead: #{example_of_belongs_to} MESSAGE end end