1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Skip StatementCache for eager loaded associations (Fixes #16761)

Eagerly loaded collection and singular associations are ignored by the StatementCache, which causes errors when the queries they generate reference columns that were not eagerly loaded.

This commit skips the creation of the StatementCache as a fix for these scenarios.
This commit is contained in:
Sammy Larbi 2014-08-31 14:18:02 -05:00
parent 40f9407b87
commit 4abbdbdf16
6 changed files with 34 additions and 3 deletions

View file

@ -407,7 +407,7 @@ module ActiveRecord
private
def get_records
return scope.to_a if reflection.scope_chain.any?(&:any?)
return scope.to_a if reflection.scope_chain.any?(&:any?) || scope.eager_loading?
conn = klass.connection
sc = reflection.association_scope_cache(conn, owner) do

View file

@ -39,7 +39,7 @@ module ActiveRecord
end
def get_records
return scope.limit(1).to_a if reflection.scope_chain.any?(&:any?)
return scope.limit(1).to_a if reflection.scope_chain.any?(&:any?) || scope.eager_loading?
conn = klass.connection
sc = reflection.association_scope_cache(conn, owner) do

View file

@ -152,6 +152,7 @@ module ActiveRecord
def find_by(*args)
return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any?
return super if default_scopes.any?
hash = args.first

View file

@ -1,9 +1,10 @@
require 'cases/helper'
require 'models/post'
require 'models/comment'
require 'models/developer'
class DefaultScopingTest < ActiveRecord::TestCase
fixtures :developers, :posts
fixtures :developers, :posts, :comments
def test_default_scope
expected = Developer.all.merge!(:order => 'salary DESC').to_a.collect { |dev| dev.salary }
@ -378,6 +379,24 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal 1, DeveloperWithIncludes.where(:audit_logs => { :message => 'foo' }).count
end
def test_default_scope_with_references_works_through_collection_association
post = PostWithCommentWithDefaultScopeReferencesAssociation.create!(title: "Hello World", body: "Here we go.")
comment = post.comment_with_default_scope_references_associations.create!(body: "Great post.", developer_id: Developer.first.id)
assert_equal comment, post.comment_with_default_scope_references_associations.to_a.first
end
def test_default_scope_with_references_works_through_association
post = PostWithCommentWithDefaultScopeReferencesAssociation.create!(title: "Hello World", body: "Here we go.")
comment = post.comment_with_default_scope_references_associations.create!(body: "Great post.", developer_id: Developer.first.id)
assert_equal comment, post.first_comment
end
def test_default_scope_with_references_works_with_find_by
post = PostWithCommentWithDefaultScopeReferencesAssociation.create!(title: "Hello World", body: "Here we go.")
comment = post.comment_with_default_scope_references_associations.create!(body: "Great post.", developer_id: Developer.first.id)
assert_equal comment, CommentWithDefaultScopeReferencesAssociation.find_by(id: comment.id)
end
unless in_memory_db?
def test_default_scope_is_threadsafe
threads = []

View file

@ -52,3 +52,8 @@ class CommentThatAutomaticallyAltersPostBody < Comment
comment.post.update_attributes(body: "Automatically altered")
end
end
class CommentWithDefaultScopeReferencesAssociation < Comment
default_scope ->{ includes(:developer).order('developers.name').references(:developer) }
belongs_to :developer
end

View file

@ -218,3 +218,9 @@ class PostThatLoadsCommentsInAnAfterSaveHook < ActiveRecord::Base
post.comments.load
end
end
class PostWithCommentWithDefaultScopeReferencesAssociation < ActiveRecord::Base
self.table_name = 'posts'
has_many :comment_with_default_scope_references_associations, foreign_key: :post_id
has_one :first_comment, class_name: "CommentWithDefaultScopeReferencesAssociation", foreign_key: :post_id
end