@@ -374,6 +374,25 @@ module ActiveRecord
374374 #
375375 # @return [AssociationMatcher]
376376 #
377+ # ##### deprecated
378+ #
379+ # Use `deprecated` to assert that the `:deprecated` option was specified.
380+ # (Enabled by default in Rails 8.1+).
381+ #
382+ # class Account < ActiveRecord::Base
383+ # belongs_to :bank, deprecated: true
384+ # end
385+ #
386+ # # RSpec
387+ # RSpec.describe Account, type: :model do
388+ # it { should belong_to(:bank).deprecated(true) }
389+ # end
390+ #
391+ # # Minitest (Shoulda)
392+ # class AccountTest < ActiveSupport::TestCase
393+ # should belong_to(:bank).deprecated(true)
394+ # end
395+ #
377396 def belong_to ( name )
378397 AssociationMatcher . new ( :belongs_to , name )
379398 end
@@ -683,7 +702,25 @@ def belong_to(name)
683702 #
684703 # @return [AssociationMatcher]
685704 #
686-
705+ # ##### deprecated
706+ #
707+ # Use `deprecated` to assert that the association is not allowed to be nil.
708+ # (Enabled by default in Rails 8.1+).
709+ #
710+ # class Vehicle < ActiveRecord::Base
711+ # delegated_type :drivable, types: %w(Car Truck), deprecated: true
712+ # end
713+ #
714+ # # RSpec
715+ # describe Vehicle
716+ # it { should have_delegated_type(:drivable).deprecated }
717+ # end
718+ #
719+ # # Minitest (Shoulda)
720+ # class VehicleTest < ActiveSupport::TestCase
721+ # should have_delegated_type(:drivable).deprecated
722+ # end
723+ #
687724 def have_delegated_type ( name )
688725 AssociationMatcher . new ( :belongs_to , name )
689726 end
@@ -972,6 +1009,25 @@ def have_delegated_type(name)
9721009 #
9731010 # @return [AssociationMatcher]
9741011 #
1012+ # ##### deprecated
1013+ #
1014+ # Use `deprecated` to assert that the `:deprecated` option was specified.
1015+ # (Enabled by default in Rails 8.1+)
1016+ #
1017+ # class Player < ActiveRecord::Base
1018+ # has_many :games, deprecated: true
1019+ # end
1020+ #
1021+ # # RSpec
1022+ # RSpec.describe Player, type: :model do
1023+ # it { should have_many(:games).deprecated(true) }
1024+ # end
1025+ #
1026+ # # Minitest (Shoulda)
1027+ # class PlayerTest < ActiveSupport::TestCase
1028+ # should have_many(:games).deprecated(true)
1029+ # end
1030+ #
9751031 def have_many ( name )
9761032 AssociationMatcher . new ( :has_many , name )
9771033 end
@@ -1219,6 +1275,25 @@ def have_many(name)
12191275 #
12201276 # @return [AssociationMatcher]
12211277 #
1278+ # ##### deprecated
1279+ #
1280+ # Use `deprecated` to assert that the `:deprecated` option was specified.
1281+ # (Enabled by default in Rails 8.1+).
1282+ #
1283+ # class Account < ActiveRecord::Base
1284+ # has_one :bank, deprecated: true
1285+ # end
1286+ #
1287+ # # RSpec
1288+ # RSpec.describe Account, type: :model do
1289+ # it { should have_one(:bank).deprecated(true) }
1290+ # end
1291+ #
1292+ # # Minitest (Shoulda)
1293+ # class AccountTest < ActiveSupport::TestCase
1294+ # should have_one(:bank).deprecated(true)
1295+ # end
1296+ #
12221297 def have_one ( name )
12231298 AssociationMatcher . new ( :has_one , name )
12241299 end
@@ -1377,6 +1452,27 @@ def have_one(name)
13771452 #
13781453 # @return [AssociationMatcher]
13791454 #
1455+ # ##### deprecated
1456+ #
1457+ # Use `deprecated` to assert that the `:deprecated` option was specified.
1458+ # (Enabled by default in Rails 8.1+).
1459+ #
1460+ # class Publisher < ActiveRecord::Base
1461+ # has_and_belongs_to_many :advertisers, deprecated: true
1462+ # end
1463+ #
1464+ # # RSpec
1465+ # RSpec.describe Publisher, type: :model do
1466+ # it { should have_and_belong_to_many(:advertisers).deprecated(true) }
1467+ # end
1468+ #
1469+ # # Minitest (Shoulda)
1470+ # class AccountTest < ActiveSupport::TestCase
1471+ # should have_and_belong_to_many(:advertisers).deprecated(true)
1472+ # end
1473+ #
1474+ # @return [AssociationMatcher]
1475+ #
13801476 def have_and_belong_to_many ( name )
13811477 AssociationMatcher . new ( :has_and_belongs_to_many , name )
13821478 end
@@ -1546,6 +1642,16 @@ def join_table(join_table_name)
15461642 self
15471643 end
15481644
1645+ def deprecated ( deprecated = true )
1646+ if ::ActiveRecord ::VERSION ::STRING >= '8.1'
1647+ @options [ :deprecated ] = deprecated
1648+ self
1649+ else
1650+ raise NotImplementedError ,
1651+ '`deprecated` association matcher is only available on Active Record >= 8.1.'
1652+ end
1653+ end
1654+
15491655 def without_validating_presence
15501656 remove_submatcher ( AssociationMatchers ::RequiredMatcher )
15511657 self
@@ -1586,7 +1692,8 @@ def matches?(subject)
15861692 touch_correct? &&
15871693 types_correct? &&
15881694 strict_loading_correct? &&
1589- submatchers_match?
1695+ submatchers_match? &&
1696+ deprecated_correct?
15901697 end
15911698
15921699 def join_table_name
@@ -1848,6 +1955,15 @@ def touch_correct?
18481955 end
18491956 end
18501957
1958+ def deprecated_correct?
1959+ if option_verifier . correct_for_boolean? ( :deprecated , options [ :deprecated ] )
1960+ true
1961+ else
1962+ @missing = "#{ name } should have deprecated: #{ options [ :deprecated ] } "
1963+ false
1964+ end
1965+ end
1966+
18511967 def types_correct?
18521968 if options . key? ( :types )
18531969 types = options [ :types ]
0 commit comments