From 8d04150709a6a0a3b5b48ccebb40fdde4b09e136 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Fri, 25 Feb 2022 23:00:37 +1030 Subject: [PATCH] Ensure Contract#metadata is reliably orderable This gets an annoyingly verbose comment, because otherwise it could be removed and continue passing almost all the time. --- activerecord/test/cases/relations_test.rb | 2 ++ activerecord/test/models/contract.rb | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 915ed55260..0a0ebf77e8 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -2108,6 +2108,8 @@ class RelationTest < ActiveRecord::TestCase test "joins with order by custom attribute" do companies = Company.create!([{ name: "test1" }, { name: "test2" }]) companies.each { |company| company.contracts.create! } + # In ordering by Contract#metadata, we rely on that JSON string to + # be consistent assert_equal companies, Company.joins(:contracts).order(:metadata, :count) assert_equal companies.reverse, Company.joins(:contracts).order(metadata: :desc, count: :desc) end diff --git a/activerecord/test/models/contract.rb b/activerecord/test/models/contract.rb index 3412d4812b..fdbbd32a1a 100644 --- a/activerecord/test/models/contract.rb +++ b/activerecord/test/models/contract.rb @@ -23,7 +23,11 @@ class Contract < ActiveRecord::Base end def update_metadata - self.metadata = { company_id: company_id, developer_id: developer_id } + # 'code' makes the JSON string consistently orderable, which is used + # by RelationsTest "joins with order by custom attribute". Without + # this it would still pass 99% of the time, but fail when two + # records' company_id lexical and numeric order differ (99, 100). + self.metadata = { code: company_id && "%08x" % company_id, company_id: company_id, developer_id: developer_id } end end