Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for horizontal sharding for Rails 6.1+ #108

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

alexeisersun
Copy link

Since Rails 6.1, it is possible for a model to connect to multiple databases. A minimal example of such application is:

class ApplicationRecord < ActiveRecord::Base
  connects_to shard: {
    defaul: { writing: :primary_db },
    shard_one: { writing: :secondary_db }
  }
end

class User < ApplicationRecord; end

ApplicationRecord.connected_to(shard: :shard_one, role: :writing) do
  User.create!(...) # creates users in secondary_db DB
end

ApplicationRecord.connection_handler.connection_pools.map { |pool|
pool.db_config.configuration_hash[:database] } # [:primary_db,
:secondary_db]

With support for multiple databases for a model, one would have something like this in tests:

DatabaseCleaner[:active_record, db: ApplicationRecord]

DatabaseCleaner.start
DatabaseCleaner.clean

In .clean, however, the bug occurs: it doesn't actually delete or truncate data from the :secondary_db.

To fix the bug, DatabaseCleaner should iterate through all connection pools the model is connected to.

Copy link
Member

@etagwerker etagwerker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexeisersun Looks good, could you please update your branch with the latest from main? Thanks!

Since Rails 6.1, it is possible for a model to connect to multiple
databases. A minimal example of such application is:

```ruby
class ApplicationRecord < ActiveRecord::Base
  connects_to shard: {
    defaul: { writing: :primary_db },
    shard_one: { writing: :secondary_db }
  }
end

class User < ApplicationRecord; end

ApplicationRecord.connected_to(shard: :shard_one, role: :writing) do
  User.create!(...) # creates users in secondary_db DB
end

ApplicationRecord.connection_handler.connection_pools.map { |pool|
pool.db_config.configuration_hash[:database] } # [:primary_db,
:secondary_db]
```

With support for multiple databases for a model, one would have something like this in tests:

```ruby
DatabaseCleaner[:active_record, db: ApplicationRecord]

DatabaseCleaner.start
DatabaseCleaner.clean
```

In `.clean`, however, the bug occurs: it doesn't actually
delete or truncate data from the :secondary_db.

To fix the bug, DatabaseCleaner should iterate through _all_ connection pools the model is connected to.
@alexeisersun alexeisersun force-pushed the rails-6.1-horizontal-sharding branch from 58c27c9 to b89a6bf Compare August 12, 2024 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants