Skip to content

Commit

Permalink
Make QueryLogs.set_context restore previous values
Browse files Browse the repository at this point in the history
It's really the least surpising behavior for block based APIs like this one
and is consistent with `with_tags`.
  • Loading branch information
byroot committed Aug 23, 2021
1 parent 9615e21 commit 6ea85af
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
8 changes: 5 additions & 3 deletions activerecord/lib/active_record/query_logs.rb
Expand Up @@ -96,13 +96,15 @@ def update_context(**options)
end

# Updates the context used to construct tags in the SQL comment during
# execution of the provided block. Resets provided values to nil after
# the block is executed.
# execution of the provided block. Resets the provided keys to their
# previous value once the block exits.
def set_context(**options)
keys = options.keys
previous_context = keys.zip(context.values_at(*keys)).to_h
update_context(**options)
yield if block_given?
ensure
update_context(**options.transform_values! { NullObject.new })
update_context(**previous_context)
end

# Temporarily tag any query executed within `&block`. Can be nested.
Expand Down
14 changes: 14 additions & 0 deletions activerecord/test/cases/query_logs_test.rb
Expand Up @@ -253,4 +253,18 @@ def test_custom_proc_context_tags
ActiveRecord::QueryLogs.update_context(foo: nil)
ActiveRecord::QueryLogs.tags = original_tags
end

def test_set_context_restore_state
original_tags = ActiveRecord::QueryLogs.tags
ActiveRecord::QueryLogs.tags = [foo: -> { context[:foo] }]
ActiveRecord::QueryLogs.set_context(foo: "bar") do
assert_sql(%r{/\*foo:bar\*/$}) { Dashboard.first }
ActiveRecord::QueryLogs.set_context(foo: "plop") do
assert_sql(%r{/\*foo:plop\*/$}) { Dashboard.first }
end
assert_sql(%r{/\*foo:bar\*/$}) { Dashboard.first }
end
ensure
ActiveRecord::QueryLogs.tags = original_tags
end
end

0 comments on commit 6ea85af

Please sign in to comment.