From 9528aa9f865cb22f3fec21dbaa9f3a434292af4e Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 3 Aug 2010 17:26:59 -0400 Subject: [PATCH] Ensure we can nest include calls [#5285 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../lib/active_record/relation/query_methods.rb | 2 +- .../lib/active_record/relation/spawn_methods.rb | 8 +++++++- activerecord/test/cases/relations_test.rb | 12 +++++++++++- activerecord/test/models/author.rb | 3 +++ activerecord/test/models/car.rb | 5 +++++ activerecord/test/models/tyre.rb | 3 +++ activerecord/test/schema/schema.rb | 4 ++++ 7 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 activerecord/test/models/tyre.rb diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index ac0b8d7245258..e8ae6a153fda1 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -11,7 +11,7 @@ module QueryMethods def includes(*args) args.reject! { |a| a.blank? } - clone.tap {|r| r.includes_values += args if args.present? } + clone.tap {|r| r.includes_values = (r.includes_values + args).flatten.uniq if args.present? } end def eager_load(*args) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 02db8d2b897cc..f857e50dea163 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -8,7 +8,13 @@ def merge(r) ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) - [:joins, :where]).each do |method| value = r.send(:"#{method}_values") - merged_relation.send(:"#{method}_values=", value) if value.present? + if value.present? + if method == :includes + merged_relation = merged_relation.includes(value) + else + merged_relation.send(:"#{method}_values=", value) + end + end end merged_relation = merged_relation.joins(r.joins_values) diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index ac7b501bb7e6a..bcc36d79bed0a 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -10,10 +10,20 @@ require 'models/developer' require 'models/company' require 'models/bird' +require 'models/car' +require 'models/engine' +require 'models/tyre' + class RelationTest < ActiveRecord::TestCase fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments, - :taggings + :taggings, :cars + + def test_two_named_scopes_with_includes_should_not_drop_any_include + car = Car.incl_engines.incl_tyres.first + assert_no_queries { car.tyres.length } + assert_no_queries { car.engines.length } + end def test_apply_relation_as_where_id posts = Post.arel_table diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index 727978431c6c1..34bfd2d881508 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -93,6 +93,9 @@ def testing_proxy_target belongs_to :author_address, :dependent => :destroy belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress" + scope :relation_include_posts, includes(:posts) + scope :relation_include_tags, includes(:tags) + attr_accessor :post_log after_initialize :set_post_log diff --git a/activerecord/test/models/car.rb b/activerecord/test/models/car.rb index 1101180a67afc..faf4e6cbc04dc 100644 --- a/activerecord/test/models/car.rb +++ b/activerecord/test/models/car.rb @@ -1,4 +1,9 @@ class Car < ActiveRecord::Base + has_many :tyres has_many :engines has_many :wheels, :as => :wheelable + + scope :incl_tyres, includes(:tyres) + scope :incl_engines, includes(:engines) + end diff --git a/activerecord/test/models/tyre.rb b/activerecord/test/models/tyre.rb new file mode 100644 index 0000000000000..bc3444aa7d85c --- /dev/null +++ b/activerecord/test/models/tyre.rb @@ -0,0 +1,3 @@ +class Tyre < ActiveRecord::Base + belongs_to :car +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index fc3810f82ba33..c72f7b25ca0b6 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -194,6 +194,10 @@ def create_table(*args, &block) t.integer :car_id end + create_table :tyres, :force => true do |t| + t.integer :car_id + end + create_table :entrants, :force => true do |t| t.string :name, :null => false t.integer :course_id, :null => false