diff options
author | Jan Habermann <jan@habermann24.com> | 2014-04-03 01:52:42 +0200 |
---|---|---|
committer | Jan Habermann <jan@habermann24.com> | 2014-04-03 01:52:42 +0200 |
commit | 98e69078d5e2fe9a13bd912bbb5da00be4d43497 (patch) | |
tree | d4da280a5a00d4ace96a3dab58bc5fbe14b93b5e | |
parent | 165d93b22ff5f8798296bd5d7642d0ddb8996c74 (diff) | |
download | rails-98e69078d5e2fe9a13bd912bbb5da00be4d43497.tar.gz rails-98e69078d5e2fe9a13bd912bbb5da00be4d43497.tar.bz2 rails-98e69078d5e2fe9a13bd912bbb5da00be4d43497.zip |
Properly handle scoping with has_many :through. Fixes #14537.
4 files changed, 25 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index ba7d2a3782..66b1616949 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -14,9 +14,14 @@ module ActiveRecord def target_scope scope = super chain.drop(1).each do |reflection| + relation = if reflection.scope + reflection.klass.all.instance_eval(&reflection.scope) + else + reflection.klass.all + end + scope.merge!( - reflection.klass.all. - except(:select, :create_with, :includes, :preload, :joins, :eager_load) + relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load) ) end scope diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 026a7fe635..fee0d2c627 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -1105,4 +1105,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_with_includes_in_through_association_scope assert_not_empty posts(:welcome).author_address_extra_with_address end + + def test_has_many_through_unscope_default_scope + post = Post.create!(:title => 'Beaches', :body => "I like beaches!") + Reader.create! :person => people(:david), :post => post + LazyReader.create! :person => people(:susan), :post => post + + assert_equal 2, post.people.to_a.size + assert_equal 1, post.lazy_people.to_a.size + + assert_equal 2, post.lazy_readers_unscope_skimmers.to_a.size + assert_equal 2, post.lazy_people_unscope_skimmers.to_a.size + end end diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index faf539a562..f52130278c 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -144,6 +144,10 @@ class Post < ActiveRecord::Base has_many :lazy_readers has_many :lazy_readers_skimmers_or_not, -> { where(skimmer: [ true, false ]) }, :class_name => 'LazyReader' + + has_many :lazy_people, :through => :lazy_readers, :source => :person + has_many :lazy_readers_unscope_skimmers, -> { skimmers_or_not }, :class_name => 'LazyReader' + has_many :lazy_people_unscope_skimmers, :through => :lazy_readers_unscope_skimmers, :source => :person def self.top(limit) ranked_by_comments.limit_by(limit) diff --git a/activerecord/test/models/reader.rb b/activerecord/test/models/reader.rb index 3a6b7fad34..14b5f60a72 100644 --- a/activerecord/test/models/reader.rb +++ b/activerecord/test/models/reader.rb @@ -15,6 +15,8 @@ end class LazyReader < ActiveRecord::Base self.table_name = "readers" default_scope -> { where(skimmer: true) } + + scope :skimmers_or_not, -> { unscope(:where => :skimmer) } belongs_to :post belongs_to :person |