Issue 1, queries sent to the replica have missing conditions
When I use .on_slave in my local dev environment (I have two databases set up locally, one replicating from the other) I don't get the results I expect. For instance this query:
=> UserActivity.where("id > 2001").on_slave.count
20012
runs this query on the replica:
2020-06-24 21:25:36.059 BST [86763] LOG: execute <unnamed>: SELECT COUNT(*) FROM "user_activities"
You can see that it's missing the where clause. If I re-run the query without the .on_slave call:
=> UserActivity.where("id > 2001").count
18025
The call is sent to the primary as expected, but this time with the clause intact:
2020-06-24 21:25:16.601 BST [87228] LOG: execute <unnamed>: SELECT COUNT(*) FROM "user_activities" WHERE (id > 2001)
If I use the block syntax then the query is sent to the replica and maintains the condition as expected and returns the correct result:
=> ActiveRecord::Base.on_slave { UserActivity.where("id > 2001").count }
18025
2020-06-24 21:34:46.614 BST [86763] LOG: execute <unnamed>: SELECT COUNT(*) FROM "user_activities" WHERE (id > 2001)
Issue 2, queries sent to the wrong server
If I make a query like this (note on_slave now appears before the .where):
UserActivity.on_slave.where("id > 2001").count
18025
The result is correct, but the query gets sent to the primary and not the replica:
2020-06-24 21:45:45.708 BST [88178] LOG: execute <unnamed>: SELECT COUNT(*) FROM "user_activities" WHERE (id > 2001)
Local setup
This is the database.yml I have in place:
development: &default
adapter: postgresql
database: connector_development
encoding: utf8
min_messages: warning
pool: <%= Integer(ENV["DB_POOL"] || 5) %>
reaping_frequency: <%= Integer(ENV["DB_REAPING_FREQUENCY"] || 10) %>
timeout: 5000
variables:
statement_timeout: 5000 # ms
connect_timeout: 1
checkout_timeout: 1
prepared_statements: false
slave:
host: 127.0.0.1
port: 5433
We are using Ruby 2.6.5 and Rails 5.0 and active_record_shards 3.17.0.