Reputation: 950
Our app is deployed on Heroku with Unicorn and master-slave database configuration with all app requests (read and write) going to master DB.
What we need is to redirect some of the read
traffic to follower (slave) database.
For achieving this, we added read_only_database_connection.rb
-
class ReadOnlyDatabaseConnection < ActiveRecord::Base
self.abstract_class = true
end
and added a mixin switch_connection.rb
module SwitchConnection
def readonly_db_connection
current_conf = ReadOnlyDatabaseConnection.connection_config
begin
ReadOnlyDatabaseConnection.establish_connection(READONLY_CONFIG).tap do
puts "Primary DB -> Follower DB"
end
yield
ensure
ReadOnlyDatabaseConnection.establish_connection(current_conf).tap do
puts "Follower DB -> Primary DB"
end
end
end
end
And then in application_controller.rb
, I did -
include SwitchConnection
around_filter :readonly_db_connection, only: [:index, :show]
Is this the right way to do this? Is there any better or safer approach to redirect all show
and index
traffic to readonly database?
Upvotes: 2
Views: 5939
Reputation: 1322
I think objects that inherit from ActiveRecord::Base
should be responsible for dealing with the database. You can have models that check the read-only slave database.
class ReadOnlyModel < ActiveRecord::Base
establish_connection 'readonly_db'
def readonly?
true
end
end
class Controller
def index
@models = ReadOnlyModel.all
end
end
# in config/database.yml
readonly_database:
adapter: #...
If you want to use the same table names (which I suspect you do), you can use the table_name method.
class Model < ActiveRecord::Base
end
class ReadOnlyModel < ActiveRecord::Base
self.table_name :models
end
Here's the documentation for the readonly?
method.
Upvotes: 5