Skip to content

Commit

Permalink
Don't use identity map if loading readonly records, this will prevent…
Browse files Browse the repository at this point in the history
… changing readonly status on already loaded records.
  • Loading branch information
miloops committed Nov 19, 2010
1 parent 448420f commit c0ad5e4
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
11 changes: 9 additions & 2 deletions activerecord/lib/active_record/relation.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -61,15 +61,22 @@ def respond_to?(method, include_private = false)
def to_a def to_a
return @records if loaded? 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 = @preload_values
preload += @includes_values unless eager_loading? preload += @includes_values unless eager_loading?
preload.each {|associations| @klass.send(:preload_associations, @records, associations) } preload.each {|associations| @klass.send(:preload_associations, @records, associations) }


# @readonly_value is true only if set explicitly. @implicit_readonly is true if there # @readonly_value is true only if set explicitly. @implicit_readonly is true if there
# are JOINS and no explicit SELECT. # are JOINS and no explicit SELECT.
readonly = @readonly_value.nil? ? @implicit_readonly : @readonly_value
@records.each { |record| record.readonly! } if readonly @records.each { |record| record.readonly! } if readonly


@loaded = true @loaded = true
Expand Down
32 changes: 26 additions & 6 deletions activerecord/test/cases/identity_map_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -242,12 +242,6 @@ def test_eager_loading_with_conditions_on_string_joined_table_preloads
assert_equal authors(:david), assert_no_queries { posts[0].author} assert_equal authors(:david), assert_no_queries { posts[0].author}
end 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 def test_reload_object_if_save_failed
developer = Developer.first developer = Developer.first
developer.salary = 0 developer.salary = 0
Expand Down Expand Up @@ -305,4 +299,30 @@ def test_associated_object_are_assigned_from_identity_map
assert_equal post.object_id, comment.post.target.object_id assert_equal post.object_id, comment.post.target.object_id
end end
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 end

0 comments on commit c0ad5e4

Please sign in to comment.