Skip to content

Commit ea61391

Browse files
committed
Allow Relation#or to accept a relation with different references
Note that the two relations must still have the same `includes` values (which is the only time `references` actually does anything). It makes sense for us to allow this, as `references` is called implicitly when passing a hash to `where`. Fixes #29411
1 parent c146065 commit ea61391

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

activerecord/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
* `Relation#or` now accepts two relations who have different values for
2+
`references` only, as `references` can be implicitly called by `where`.
3+
4+
Fixes #29411.
5+
6+
*Sean Griffin*
7+
18
* ApplicationRecord is no longer generated when generating models. If you
29
need to generate it, it can be created with `rails g application_record`.
310

activerecord/lib/active_record/relation/query_methods.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ def or!(other) # :nodoc:
635635

636636
self.where_clause = self.where_clause.or(other.where_clause)
637637
self.having_clause = having_clause.or(other.having_clause)
638+
self.references_values += other.references_values
638639

639640
self
640641
end
@@ -1158,7 +1159,7 @@ def check_if_method_has_arguments!(method_name, args)
11581159
end
11591160
end
11601161

1161-
STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope]
1162+
STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope, :references]
11621163
def structurally_incompatible_values_for_or(other)
11631164
STRUCTURAL_OR_METHODS.reject do |method|
11641165
get_value(method) == other.get_value(method)

activerecord/test/cases/relation/or_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
# frozen_string_literal: true
22

33
require "cases/helper"
4+
require "models/author"
5+
require "models/categorization"
46
require "models/post"
57

68
module ActiveRecord
79
class OrTest < ActiveRecord::TestCase
810
fixtures :posts
11+
fixtures :authors
912

1013
def test_or_with_relation
1114
expected = Post.where("id = 1 or id = 2").to_a
@@ -115,5 +118,13 @@ def test_or_with_non_relation_object_raises_error
115118
Post.where(id: [1, 2, 3]).or(title: "Rails")
116119
end
117120
end
121+
122+
def test_or_with_references_inequality
123+
joined = Post.includes(:author)
124+
actual = joined.where(authors: { id: 1 })
125+
.or(joined.where(title: "I don't have any comments"))
126+
expected = Author.find(1).posts + Post.where(title: "I don't have any comments")
127+
assert_equal expected.sort_by(&:id), actual.sort_by(&:id)
128+
end
118129
end
119130
end

0 commit comments

Comments
 (0)