# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1373 def primary_key_correct?(klass) if options.key?(:primary_key) if option_verifier.correct_for_string?(:primary_key, options[:primary_key]) true else @missing = "#{klass} does not have a #{options[:primary_key]} primary key" false end else true end end
class Shoulda::Matchers::ActiveRecord::AssociationMatcher
@private
Attributes
macro[R]
missing[R]
name[R]
options[R]
subject[R]
submatchers[R]
Public Class Methods
new(macro, name)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 993 def initialize(macro, name) @macro = macro @name = name @options = {} @submatchers = [] @missing = '' if macro == :belongs_to && RailsShim.active_record_gte_5? required(belongs_to_required_by_default?) end end
Public Instance Methods
autosave(autosave)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1064 def autosave(autosave) @options[:autosave] = autosave self end
class_name(class_name)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1074 def class_name(class_name) @options[:class_name] = class_name self end
conditions(conditions)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1059 def conditions(conditions) @options[:conditions] = conditions self end
counter_cache(counter_cache = true)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1032 def counter_cache(counter_cache = true) add_submatcher( AssociationMatchers::CounterCacheMatcher, counter_cache, name, ) self end
dependent(dependent)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1014 def dependent(dependent) add_submatcher( AssociationMatchers::DependentMatcher, dependent, name, ) self end
description()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1129 def description description = "#{macro_description} #{name}" description += " class_name => #{options[:class_name]}" if options.key?(:class_name) [description, submatchers.map(&:description)].flatten.join(' ') end
failure_message()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1135 def failure_message "Expected #{expectation} (#{missing_options})" end
failure_message_when_negated()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1139 def failure_message_when_negated "Did not expect #{expectation}" end
index_errors(index_errors)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1069 def index_errors(index_errors) @options[:index_errors] = index_errors self end
inverse_of(inverse_of)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1041 def inverse_of(inverse_of) add_submatcher( AssociationMatchers::InverseOfMatcher, inverse_of, name, ) self end
join_table(join_table_name)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1119 def join_table(join_table_name) @options[:join_table_name] = join_table_name self end
join_table_name()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1160 def join_table_name options[:join_table_name] || reflector.join_table_name end
matches?(subject)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1143 def matches?(subject) @subject = subject association_exists? && macro_correct? && (polymorphic? || class_exists?) && foreign_key_exists? && primary_key_exists? && class_name_correct? && join_table_correct? && autosave_correct? && index_errors_correct? && conditions_correct? && validate_correct? && touch_correct? && submatchers_match? end
option_verifier()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1164 def option_verifier @option_verifier ||= AssociationMatchers::OptionVerifier.new(reflector) end
optional()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1099 def optional remove_submatcher(AssociationMatchers::RequiredMatcher) add_submatcher( AssociationMatchers::OptionalMatcher, name, true, ) self end
order(order)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1023 def order(order) add_submatcher( AssociationMatchers::OrderMatcher, order, name, ) self end
required(required = true)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1089 def required(required = true) remove_submatcher(AssociationMatchers::OptionalMatcher) add_submatcher( AssociationMatchers::RequiredMatcher, name, required, ) self end
source(source)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1050 def source(source) add_submatcher( AssociationMatchers::SourceMatcher, source, name, ) self end
through(through)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1005 def through(through) add_submatcher( AssociationMatchers::ThroughMatcher, through, name, ) self end
touch(touch = true)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1114 def touch(touch = true) @options[:touch] = touch self end
validate(validate = true)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1109 def validate(validate = true) @options[:validate] = validate self end
with_foreign_key(foreign_key)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1079 def with_foreign_key(foreign_key) @options[:foreign_key] = foreign_key self end
with_primary_key(primary_key)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1084 def with_primary_key(primary_key) @options[:primary_key] = primary_key self end
without_validating_presence()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1124 def without_validating_presence remove_submatcher(AssociationMatchers::RequiredMatcher) self end
Protected Instance Methods
add_submatcher(matcher_class, *args)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1176 def add_submatcher(matcher_class, *args) remove_submatcher(matcher_class) submatchers << matcher_class.new(*args) end
association_exists?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1223 def association_exists? if reflection.nil? @missing = "no association called #{name}" false else true end end
autosave_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1302 def autosave_correct? if options.key?(:autosave) if option_verifier.correct_for_boolean?(:autosave, options[:autosave]) true else @missing = "#{name} should have autosave set to #{options[:autosave]}" false end else true end end
belongs_foreign_key_missing?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1257 def belongs_foreign_key_missing? macro == :belongs_to && !class_has_foreign_key?(model_class) end
belongs_to_required_by_default?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1414 def belongs_to_required_by_default? ::ActiveRecord::Base.belongs_to_required_by_default end
class_exists?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1294 def class_exists? associated_class true rescue NameError @missing = "#{reflection.class_name} does not exist" false end
class_has_foreign_key?(klass)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1362 def class_has_foreign_key?(klass) if options.key?(:foreign_key) option_verifier.correct_for_string?(:foreign_key, options[:foreign_key]) elsif column_names_for(klass).include?(foreign_key) true else @missing = "#{klass} does not have a #{foreign_key} foreign key." false end end
class_name_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1267 def class_name_correct? if options.key?(:class_name) if option_verifier.correct_for_constant?(:class_name, options[:class_name]) true else @missing = "#{name} should resolve to #{options[:class_name]} for class_name" false end else true end end
column_names_for(klass)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1408 def column_names_for(klass) klass.column_names rescue ::ActiveRecord::StatementInvalid [] end
conditions_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1331 def conditions_correct? if options.key?(:conditions) if option_verifier.correct_for_relation_clause?(:conditions, options[:conditions]) true else @missing = "#{name} should have the following conditions: #{options[:conditions]}" false end else true end end
expectation()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1200 def expectation "#{model_class.name} to have a #{macro} association called #{name}" end
failing_submatchers()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1209 def failing_submatchers @failing_submatchers ||= submatchers.select do |matcher| !matcher.matches?(subject) end end
foreign_key()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1386 def foreign_key if foreign_key_reflection if foreign_key_reflection.respond_to?(:foreign_key) foreign_key_reflection.foreign_key.to_s else foreign_key_reflection.primary_key_name.to_s end end end
foreign_key_exists?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1249 def foreign_key_exists? !(belongs_foreign_key_missing? || has_foreign_key_missing?) end
foreign_key_reflection()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1396 def foreign_key_reflection if [:has_one, :has_many].include?(macro) && reflection.options.include?(:inverse_of) associated_class.reflect_on_association(reflection.options[:inverse_of]) else reflection end end
has_foreign_key_missing?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1261 def has_foreign_key_missing? [:has_many, :has_one].include?(macro) && !through? && !class_has_foreign_key?(associated_class) end
index_errors_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1315 def index_errors_correct? return true unless options.key?(:index_errors) if option_verifier.correct_for_boolean?( :index_errors, options[:index_errors] ) true else @missing = "#{name} should have index_errors set to " + "#{options[:index_errors]}" false end end
join_table_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1280 def join_table_correct? if macro != :has_and_belongs_to_many || join_table_matcher.matches?(@subject) true else @missing = join_table_matcher.failure_message false end end
join_table_matcher()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1289 def join_table_matcher @join_table_matcher ||= AssociationMatchers::JoinTableMatcher.new(self, reflector) end
macro_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1232 def macro_correct? if reflection.macro == macro true elsif reflection.macro == :has_many macro == :has_and_belongs_to_many && reflection.name == @name else @missing = "actual association type was #{reflection.macro}" false end end
macro_description()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1187 def macro_description case macro.to_s when 'belongs_to' 'belong to' when 'has_many' 'have many' when 'has_one' 'have one' when 'has_and_belongs_to_many' 'have and belong to many' end end
macro_supports_primary_key?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1244 def macro_supports_primary_key? macro == :belongs_to || ([:has_many, :has_one].include?(macro) && !through?) end
missing_options()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1204 def missing_options missing_options = [missing, missing_options_for_failing_submatchers] missing_options.flatten.select(&:present?).join(', ') end
missing_options_for_failing_submatchers()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1215 def missing_options_for_failing_submatchers if defined?(@failing_submatchers) @failing_submatchers.map(&:missing_option) else [] end end
primary_key_correct?(klass)
click to toggle source
primary_key_exists?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1253 def primary_key_exists? !macro_supports_primary_key? || primary_key_correct?(model_class) end
reflector()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1172 def reflector @reflector ||= AssociationMatchers::ModelReflector.new(subject, name) end
remove_submatcher(matcher_class)
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1181 def remove_submatcher(matcher_class) submatchers.delete_if do |submatcher| submatcher.is_a?(matcher_class) end end
submatchers_match?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1404 def submatchers_match? failing_submatchers.empty? end
touch_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1353 def touch_correct? if option_verifier.correct_for_boolean?(:touch, options[:touch]) true else @missing = "#{name} should have touch: #{options[:touch]}" false end end
validate_correct?()
click to toggle source
# File lib/shoulda/matchers/active_record/association_matcher.rb, line 1344 def validate_correct? if option_verifier.correct_for_boolean?(:validate, options[:validate]) true else @missing = "#{name} should have validate: #{options[:validate]}" false end end