Connection switching to support multiple databases is not working in Rails 6.0.0.beta3 version

I followed some tutorials on new release Rails 6.0.0.beta3 and trying to implement connection switching multiple database this way:

database.yml

default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: root
socket: /var/run/mysqld/mysqld.
sock
development:
  main:
    <<: *default
    database: r6_multidb_development
main_replica:
    <<: *default
    database: r6_multidb_development_copy
replica: true

Article Model

class Article < ApplicationRecord
  connect_to database: { writing: :main, reading: :main_replica }
end

Hey!

I’ve implemented multiple databases in Rails 6, but I didn’t implement multiple writers. Rails doesn’t know what your replica configuration is going to be like so for purposes of local development you should use the same database name for your primary and replica, and then have different user names. In production you should also use the same name (they are the same data you’re accessing) with different usernames (one set to readonly) but they shouldn’t be in the same place.

Hope that helps,

Eileen

Ok after reading this over a few times I’ve realized that you wrote broken code on purpose to prove the switching was working.

Did you turn on the middleware that will automatically swap based on HTTP verb? If you didn’t your POST/GET requests won’t switch connections automatically.

If you’re in a model/controller/test you need to wrap it in a connected_to block like this


ActiveRecord::Base.connected_to(role: :reading) do

# read from your replica

end

Rails can’t know if your replica is up to date so we didn’t implement always select from the replica, you have to tell it you want that.

I guess middleware should turn on when we write connect_to blog on the model in order to switch read and write access, isn’t that?

class Article < ApplicationRecord connect_to database: { writing: :main, reading: :main_replica } end

Hi Eileen, yes this way I had already tested and it works, but by keeping different usernames for same database doesn’t mean there are two database. But I would like to keep two database one is for Post/Put and other database just for GET and reading large queries no matter both the database are same just name is changed, is this possible with connects_to() ?

Also I have added connected_to() inside action but I did not get the desired result from r6_multidb_development_copy, may be I am missing something.

def index ActiveRecord::Base.connected_to(role: :reading) do @articles = Article.all end end

``

The middleware needs to be configured in your environment so that you can set the replica delay. See the docs here https://github.com/rails/rails/blob/713cee01a5391b1ca56e25883c6c172ae59d7020/activerecord/lib/active_record/middleware/database_selector.rb#L33-L36. This behavior s by design, and it should not turn on when you call connect_to.

Thank you Eileen, it is working as expected and i understand now.

I’m curious what tutorial you followed, I’m wondering if it’s incorrect and we need to fix something. I also need to write docs in Rails itself before the 6 final is released.

Here is the tutorial i followed: What’s coming to Rails 6.0?. Rails 6.0 will be released soon and… | by Guy Maliar | Ruby Inside | Medium

Please also let me know if any changes i need to make in my code or if have any suggestions, thank you.