Skip to content

Commit

Permalink
Implement connecting_to method
Browse files Browse the repository at this point in the history
Sometimes you need to have a different default connection but aren't
calling the connection with a block. An example is booting a console in
`reading` mode. This adds the ability for a script to set a specific
connection on boot while preserving the behavior of `connected_to` for
application code.
  • Loading branch information
eileencodes committed Oct 29, 2020
1 parent 60d5928 commit 231bcc7
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
17 changes: 17 additions & 0 deletions activerecord/lib/active_record/connection_handling.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,23 @@ def connected_to(database: nil, role: nil, shard: nil, prevent_writes: false, &b
end
end

# Use a specified connection.
#
# This method is useful for ensuring that a specific connection is
# being used. For example, when booting a console in readonly mode.
#
# It is not recommended to use this method in a request since it
# does not yield to a block like `connected_to`.
def connecting_to(role: default_role, shard: default_shard, prevent_writes: false)
if legacy_connection_handling
raise NotImplementedError, "`connecting_to` is not available with `legacy_connection_handling`."
end

prevent_writes = true if role == reading_role

self.connected_to_stack << { role: role, shard: shard, prevent_writes: prevent_writes, klass: self }
end

def while_preventing_writes(enabled = true, &block)
connected_to(role: current_role, prevent_writes: enabled, &block)
end
Expand Down
37 changes: 37 additions & 0 deletions activerecord/test/cases/base_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1651,4 +1651,41 @@ def test_protected_environments_are_stored_as_an_array_of_string
assert AbstractCompany.connected_to?(role: :reading, shard: :default)
end
end

test "#connecting_to with role" do
AbstractCompany.connecting_to(role: :reading)

assert AbstractCompany.connected_to?(role: :reading)
assert AbstractCompany.current_preventing_writes
ensure
ActiveRecord::Base.connected_to_stack.pop
end

test "#connecting_to with role and shard" do
AbstractCompany.connecting_to(role: :reading, shard: :default)

assert AbstractCompany.connected_to?(role: :reading, shard: :default)
ensure
ActiveRecord::Base.connected_to_stack.pop
end

test "#connecting_to with prevent_writes" do
AbstractCompany.connecting_to(role: :writing, prevent_writes: true)

assert AbstractCompany.connected_to?(role: :writing)
assert AbstractCompany.current_preventing_writes
ensure
ActiveRecord::Base.connected_to_stack.pop
end

test "#connecting_to doesn't work with legacy connection handling" do
old_value = ActiveRecord::Base.legacy_connection_handling
ActiveRecord::Base.legacy_connection_handling = true

assert_raises NotImplementedError do
AbstractCompany.connecting_to(role: :writing, prevent_writes: true)
end
ensure
ActiveRecord::Base.legacy_connection_handling = old_value
end
end

0 comments on commit 231bcc7

Please sign in to comment.