diff --git a/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb b/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb index b012f8b33..ae3558be5 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb @@ -19,10 +19,7 @@ def description def matches?(subject) self.subject = ModelReflector.new(subject, name) - if option_verifier.correct_for_string?( - :counter_cache, - counter_cache, - ) + if correct_value? true else self.missing_option = "#{name} should have #{description}" @@ -34,9 +31,42 @@ def matches?(subject) attr_accessor :subject, :counter_cache, :name + def correct_value? + expected = normalize_value + + if expected.is_a?(Hash) + option_verifier.correct_for_hash?( + :counter_cache, + expected, + ) + else + option_verifier.correct_for_string?( + :counter_cache, + expected, + ) + end + end + def option_verifier @_option_verifier ||= OptionVerifier.new(subject) end + + def normalize_value + if Rails::VERSION::STRING >= '7.2' + case counter_cache + when true + { active: true, column: nil } + when String, Symbol + { active: true, column: counter_cache.to_s } + when Hash + ({ active: true }).merge(counter_cache) + else + raise ArgumentError, 'Invalid counter_cache option' + end + else + counter_cache + end + end end end end