Proposal: a way to handle multi-DB ActiveRecord setups · Issue #5264 · heartcombo/devise

Ask questions Research chat →

https://github.com/heartcombo/devise/issues/5264 · scraped

rails

Attachments

Scraped Content

— 499 words · 2026-02-14 17:43:58 UTC ·

Excerpt

![](https://prod-files-secure.s3.us-west-2.amazonaws.com/871f1661-80b8-4d0c-ac3b-2adfc6ff4c66/632bf277-0b92-4dce-9c50-18a1b8c5e287/5264?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=ASIAZI2LB4662DPJN36B%2F20260214%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20260214T174352Z&X-Amz-Expires=3600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEEEaCXVzLXdlc3QtMiJGMEQCIAJjg7by6qLaKvEh%2F9qdfV45p9K1sGv0bgyy1r7HVUpRAiAMdmNyS5ETa1ts9u4OMU8%2BFpZcY6n89rMD5mHD0BLUYSr%2FAwgKEAAaDDYzNzQyMzE4MzgwNSIMDoErB%2Fwwy%2FRoUCxXKtwD5l%2BgGcuOtXsfCV4xiJK1KdYwtr1XFIJmvjb1UETMdAeweSZ2lONysZsp3Ee39Hk%2FeJY3oOmDf4JQJWYjSZAB%2F83MD5RqECVzCZertOvajahVQ9r1alYfZXYI5BTCBkjPJ5uP0l0cD6oxdUVA0w9dsvaCSw9D12eNo3FyIMLeLhIopZZ0EZIZgpHXgk0VIJ0PjC7TrcHU22d799W248c1eBnGvIwCD2uv5G%2FyZqJRqHzzQCXvIPzoojtX2YdQIiv2f5BnAz3NHql8wxJKHYnzJUgSY9mmue3H1xv7oc9m6EXtZSm4GrEAS6IGQR1RzMxyHMWejd%2Bx2AyVsGSqu4%2FQVg4%2F1J4bATemZ7UE%2BlTJmK%2Fu7yX2%2FPklS3EZZawV8vzTrkFabsDTbUiKrqJii8NYZQD24lH0Cl5AbPRZ7%2BWoiTr5Oj5j
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/871f1661-80b8-4d0c-ac3b-2adfc6ff4c66/632bf277-0b92-4dce-9c50-18a1b8c5e287/5264?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=ASIAZI2LB4662DPJN36B%2F20260214%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20260214T174352Z&X-Amz-Expires=3600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEEEaCXVzLXdlc3QtMiJGMEQCIAJjg7by6qLaKvEh%2F9qdfV45p9K1sGv0bgyy1r7HVUpRAiAMdmNyS5ETa1ts9u4OMU8%2BFpZcY6n89rMD5mHD0BLUYSr%2FAwgKEAAaDDYzNzQyMzE4MzgwNSIMDoErB%2Fwwy%2FRoUCxXKtwD5l%2BgGcuOtXsfCV4xiJK1KdYwtr1XFIJmvjb1UETMdAeweSZ2lONysZsp3Ee39Hk%2FeJY3oOmDf4JQJWYjSZAB%2F83MD5RqECVzCZertOvajahVQ9r1alYfZXYI5BTCBkjPJ5uP0l0cD6oxdUVA0w9dsvaCSw9D12eNo3FyIMLeLhIopZZ0EZIZgpHXgk0VIJ0PjC7TrcHU22d799W248c1eBnGvIwCD2uv5G%2FyZqJRqHzzQCXvIPzoojtX2YdQIiv2f5BnAz3NHql8wxJKHYnzJUgSY9mmue3H1xv7oc9m6EXtZSm4GrEAS6IGQR1RzMxyHMWejd%2Bx2AyVsGSqu4%2FQVg4%2F1J4bATemZ7UE%2BlTJmK%2Fu7yX2%2FPklS3EZZawV8vzTrkFabsDTbUiKrqJii8NYZQD24lH0Cl5AbPRZ7%2BWoiTr5Oj5jqH2mBDdgObKXFfopWL6VTV4JW21iF0dFFW7bOvh6clduie%2BQ2oQ6yb5Nz8a2G%2BVg1zr85hGg8nAlVEOliub%2F0X0hqTJ83PtHh%2FaFW8TdM%2Fi1kDp4u0EbZ4Q6eX1IPKMTs0lbI1gOlS7DZDHXIX2dmnBpOk2pXkFnhy3kj7U3RKY4ll%2BL7jD7s9Fa%2F8k5kob%2FKJkuwGpth6YwndHCzAY6pgFp7ubFSWf0v8uqaHcNKiNAxbwKAm248YY%2BwcnrzS9dyq9JA5kISCmQ8O%2Bn7km0A%2B1j5a5bI9r35TC7hCJfLJien%2BOwILEuzR0%2F5S6R7A6Pe9ss0zNtkiaYUXWrc1Ig95DzRU%2Fw0YKiSCEBjgH5DTtdYuPcutsyDX00TXUe4te7xCw8AVTdXdEvGOWhkhbADrBQMrrQM8GfN0Yhxv4ALWu%2BczwByD%2B2&X-Amz-Signature=1b350f646933693b0a95f9dff099315067511df13af588ce3dc977a2a733d8f2&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) Rails 6 provides connection switching to allow for applications with multiple databases. One of the supported behaviors is a primary/replica setup where the replica database is read-only. Devise users will run into some issues with the default Rails 6 connection switching, as it restricts writes to non-GET/HEAD/OPTIONS requests. As a result, some requests will trigger ActiveRecord::ReadOnlyError as a result of hooks firing, etc. Some of the Devise methods can be worked around directly in models like this: Unfortunately some of the cases where writes inside a GET request don't seem quite as straightforward to work around. Some of the Warden after_sign_in hooks call #save directly on the model. Since Warden hooks are additive, it's not easy to replace the hook with a monkey-patched one. We're currently experiencing some failures for lockable that we (believe we) are not able to code around without forking Devise. Example: I'd like to propose a pull request to make the Rails 6 primary/replica functionality work without requiring any changes for users who are on older versions of Rails or who aren't leveraging ActiveRecord's connected_to functionality. There are two ways I can see to approach this: 1. Require users to wrap their model methods in a connected_to clause around super as described above. hooks/lockable would need to be updated to push its call to #save to a model method which could then be wrapped. Then we would document that this is the recommended approach for users leveraging primary/replica setups. This would be the smallest change, but would be less convenient for multiple-database users in Rails 6. 2. Add a new configuration option, something named like devise_database_role. If that role is set, then all model saves in model modules or hooks would get wrapped in a connected_to block using that role. If the setting is not defined, then all saves happen directly as now. This approach would be more comprehensive and be a one-stop change for primary/replica setups vs. needing to patch each relevant method, but requires more invasive changes across several model modules. I'm excited to tackle either of these changes, but looking for feedback on the preferred approach. GuillaumeGillet commented on Aug 12, 2021 So based on what I read, I end up doing in my user model : def update_tracked_fields!(request) User.connected_to(role: :writing) do super end end def update_tracked_fields(request) User.connected_to(role: :writing) do super end end def remember_me! User.connected_to(role: :writing) do super end end def forget_me! User.connected_to(role: :writing) do super end end So, so far, there is no global hook to do that. Am I right? vitobotta commented on Sep 23, 2019 Hi @colinross , in the meantime I ended up doing something similar with an around filter for all the Devise actions just to be sure: around_action :ensure_primary_database, if: :devise_controller? ... def ensure_primary_database ActiveRecord::Base.connected_to(role: :writing) do ActiveRecord::Base.connection_handler.while_preventing_writes(false) do yield end end end This solved my original problem, so I had forgotten about it. I agree with what you said about Devise, perhaps it's a non-issue so I'm closing. Thank you for your reply.

Visibility

Visible to everyone

Reading Status

Related Bookmarks

My Note


Saved!

Annotations

Export as Markdown
+ Annotate selection

Add Annotation