Skip to content

Commit

Permalink
Allow Relation#or to accept a relation with different references
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sgrif committed Jul 25, 2017
1 parent c146065 commit ea61391
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
7 changes: 7 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
* `Relation#or` now accepts two relations who have different values for
`references` only, as `references` can be implicitly called by `where`.

Fixes #29411.

*Sean Griffin*

* ApplicationRecord is no longer generated when generating models. If you
need to generate it, it can be created with `rails g application_record`.

Expand Down
3 changes: 2 additions & 1 deletion activerecord/lib/active_record/relation/query_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ def or!(other) # :nodoc:

self.where_clause = self.where_clause.or(other.where_clause)
self.having_clause = having_clause.or(other.having_clause)
self.references_values += other.references_values

self
end
Expand Down Expand Up @@ -1158,7 +1159,7 @@ def check_if_method_has_arguments!(method_name, args)
end
end

STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope]
STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope, :references]
def structurally_incompatible_values_for_or(other)
STRUCTURAL_OR_METHODS.reject do |method|
get_value(method) == other.get_value(method)
Expand Down
11 changes: 11 additions & 0 deletions activerecord/test/cases/relation/or_test.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# frozen_string_literal: true

require "cases/helper"
require "models/author"
require "models/categorization"
require "models/post"

module ActiveRecord
class OrTest < ActiveRecord::TestCase
fixtures :posts
fixtures :authors

def test_or_with_relation
expected = Post.where("id = 1 or id = 2").to_a
Expand Down Expand Up @@ -115,5 +118,13 @@ def test_or_with_non_relation_object_raises_error
Post.where(id: [1, 2, 3]).or(title: "Rails")
end
end

def test_or_with_references_inequality
joined = Post.includes(:author)
actual = joined.where(authors: { id: 1 })
.or(joined.where(title: "I don't have any comments"))
expected = Author.find(1).posts + Post.where(title: "I don't have any comments")
assert_equal expected.sort_by(&:id), actual.sort_by(&:id)
end
end
end

0 comments on commit ea61391

Please sign in to comment.