There is a Rails 5 application that runs in Heroku; it has two DBs, a Primary and a Follower (read-only), the follower is the replica of the Primary. In some application areas, we use followers to get the data. Previously, rails didn't support Multi DB, so we used the Gem Octopus. However, they put it in maintenance mode as the Rails 6 supports the Multi DB.
We used different ways to access the follower db through octopus like:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
class SetupController < ApplicationController
around_action :select_follower
def select_follower(&block)
Octopus.using(ENV['FOLLOWER_DB'], &block)
end
def method1
// enter code here
end
end
@customer = Customer.using(FOLLOWER_DB).find(params[:id])
Octopus.using(:master) do
SidekiqWorker.perform_async(param1, param2)
end
It was working fine and this has been running for more than 5 years.
Recently We have migrated our Rails application to Rails 6 from 5 and we replaced the octopus with multi DB setup.
database.yml
production:
primary:
<<: *default
url: <%= ENV['DATABASE_URL'] %>
secondary:
<<: *default
url: <%= ENV['FOLLOWER_DATABASE_URL'] %>
migrations_paths: db/secondary_migrate
app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
connects_to database: { writing: :primary, reading: :primary }
end
app/models/secondary_application_record.rb
class SecondaryApplicationRecord < ActiveRecord::Base
self.abstract_class = true
connects_to database: { writing: :secondary, reading: :secondary }
end
Then when we try to access the follower as we done the same way with octopus, like
class DashboardController < ApplicationController
around_action :select_secondary_db
def select_secondary_db(&block)
SecondaryApplicationRecord.connected_to(role: :reading, &block)
end
def method1
// enter code here
end
end
or
SecondaryApplicationRecord.connected_to(role: :reading) do
Customer.find_by_id(params[:id])
end
In all this new way, the logs shows the query runs in primary db, nothing runs through follower/secondary DB. What could be the case that run always through primary?
Customerinherits fromApplicationRecordand as such it uses the reading role defined. You could try using the sharding syntax instead. Docs. It says it is for horizontal sharding but it seems like it should work fine for vertical sharding.