diff options
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 11 | ||||
-rw-r--r-- | activerecord/test/cases/identity_map_test.rb | 32 |
2 files changed, 35 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 3b22be78cb..b91ecb109a 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -61,7 +61,15 @@ module ActiveRecord def to_a return @records if loaded? - @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql, @bind_values) + readonly = @readonly_value.nil? ? @implicit_readonly : @readonly_value + + @records = if readonly + IdentityMap.without do + eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql, @bind_values) + end + else + eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql, @bind_values) + end preload = @preload_values preload += @includes_values unless eager_loading? @@ -69,7 +77,6 @@ module ActiveRecord # @readonly_value is true only if set explicitly. @implicit_readonly is true if there # are JOINS and no explicit SELECT. - readonly = @readonly_value.nil? ? @implicit_readonly : @readonly_value @records.each { |record| record.readonly! } if readonly @loaded = true diff --git a/activerecord/test/cases/identity_map_test.rb b/activerecord/test/cases/identity_map_test.rb index e62e99361a..5edbd34be2 100644 --- a/activerecord/test/cases/identity_map_test.rb +++ b/activerecord/test/cases/identity_map_test.rb @@ -242,12 +242,6 @@ class IdentityMapTest < ActiveRecord::TestCase assert_equal authors(:david), assert_no_queries { posts[0].author} end - # Second search should not change read only status for collection - def test_find_with_joins_option_implies_readonly - Developer.joins(', projects').each { |d| assert d.readonly? } - Developer.joins(', projects').readonly(false).each { |d| assert d.readonly? } - end - def test_reload_object_if_save_failed developer = Developer.first developer.salary = 0 @@ -305,4 +299,30 @@ class IdentityMapTest < ActiveRecord::TestCase assert_equal post.object_id, comment.post.target.object_id end end + + def test_find_using_identity_map_respects_readonly_when_loading_associated_object_first + author = Author.first + readonly_comment = author.readonly_comments.first + + comment = Comment.first + assert !comment.readonly? + + assert readonly_comment.readonly? + + assert_raise(ActiveRecord::ReadOnlyRecord) {readonly_comment.save} + assert comment.save + end + + def test_find_using_identity_map_respects_readonly + comment = Comment.first + assert !comment.readonly? + + author = Author.first + readonly_comment = author.readonly_comments.first + + assert readonly_comment.readonly? + + assert_raise(ActiveRecord::ReadOnlyRecord) {readonly_comment.save} + assert comment.save + end end |