diff options
Diffstat (limited to 'activerecord')
7 files changed, 26 insertions, 24 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index a656c767c0..1ff7010c2f 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -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`. diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec index 7b62c98c6e..7ad06fe840 100644 --- a/activerecord/activerecord.gemspec +++ b/activerecord/activerecord.gemspec @@ -31,5 +31,5 @@ Gem::Specification.new do |s| s.add_dependency "activesupport", version s.add_dependency "activemodel", version - s.add_dependency "arel", "~> 8.0" + s.add_dependency "arel", "9.0.0.alpha" end diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb index 2c3d5b3429..dc029c08bd 100644 --- a/activerecord/lib/active_record/associations/join_dependency.rb +++ b/activerecord/lib/active_record/associations/join_dependency.rb @@ -174,9 +174,9 @@ module ActiveRecord def make_join_constraints(parent, child, join_type, aliasing = false) tables = aliasing ? table_aliases_for(parent, child) : child.tables - info = make_constraints(parent, child, tables, join_type) + joins = make_constraints(parent, child, tables, join_type) - [info] + child.children.flat_map { |c| make_join_constraints(child, c, join_type, aliasing) } + joins.concat child.children.flat_map { |c| make_join_constraints(child, c, join_type, aliasing) } end def table_aliases_for(parent, node) diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb index 30dbdb7fa5..a526468bf6 100644 --- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb @@ -23,8 +23,6 @@ module ActiveRecord super && reflection == other.reflection end - JoinInformation = Struct.new :joins - def join_constraints(foreign_table, foreign_klass, join_type, tables, chain) joins = [] tables = tables.reverse @@ -51,7 +49,7 @@ module ActiveRecord foreign_table, foreign_klass = table, klass end - JoinInformation.new joins + joins end def table diff --git a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb index ad617365fc..2fd75c8958 100644 --- a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb +++ b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb @@ -9,7 +9,6 @@ module ActiveRecord def call(attribute, value) return attribute.in([]) if value.empty? - return queries_predicates(value) if value.all? { |v| v.is_a?(Hash) } values = value.map { |x| x.is_a?(Base) ? x.id : x } nils, values = values.partition(&:nil?) @@ -44,17 +43,6 @@ module ActiveRecord other end end - - private - def queries_predicates(queries) - if queries.size > 1 - queries.map do |query| - Arel::Nodes::And.new(predicate_builder.build_from_hash(query)) - end.inject(&:or) - else - predicate_builder.build_from_hash(queries.first) - end - end end end end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 812c8e7e3f..f7fe968b55 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -635,6 +635,7 @@ module ActiveRecord 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 @@ -1014,11 +1015,8 @@ module ActiveRecord klass, table, association_joins, join_list ) - join_infos = join_dependency.join_constraints stashed_association_joins, join_type - - join_infos.each do |info| - info.joins.each { |join| manager.from(join) } - end + joins = join_dependency.join_constraints(stashed_association_joins, join_type) + joins.each { |join| manager.from(join) } manager.join_sources.concat(join_list) @@ -1161,7 +1159,7 @@ module ActiveRecord 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) diff --git a/activerecord/test/cases/relation/or_test.rb b/activerecord/test/cases/relation/or_test.rb index 3269620987..b01801b41f 100644 --- a/activerecord/test/cases/relation/or_test.rb +++ b/activerecord/test/cases/relation/or_test.rb @@ -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 @@ -115,5 +118,13 @@ module ActiveRecord 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 |