The parent class for models that are persisted on a different database app/models/public_database_model.rb
:
# Public: Provide a base class for accessing the public database.
# All models inheriting from this class will use by default the data store DB.
class PublicDatabaseModel < ActiveRecord::Base
# Tell Active Record (AR) to not look up for a table called like this class,
# since this class is only used to add custom config for AR
self.abstract_class = true
databases = YAML::load(ERB.new(IO.read('config/database_public.yml')).result)
establish_connection(databases[Rails.env])
end
Hack to have extra tasks for the second datatbase. lib/tasks/databases.rake
:
# Public: This Rake file tries to add what rails provides on the
# databases.rake but for building on top of custom databases.
# Basically we get the nice db:migrate but for using it on a different DB than
# the default, by calling it with the namespace defined here.
#
# In order to be able to use the default rails rake commands but on a different
# DB, we are first updating the Rails.application.config.paths and then
# calling the original rake task. Rails.application.config.paths is getting
# loaded and available as soon as we call rake since the rakefile in a rails
# project declares that. Look at Rakefile in the project root for more details.
# Public: Access to the same commands you do for DB operations,
# like db:drop, db:migrate but using the public namespace, this will
# execute on top of the public DB.
namespace :public do
# Configure the variables that rails need in order to look up for the db configuration in a different folder
task :set_custom_db_config_paths do
# This is the minimum required to tell rails to use a different location
# for all the files related to the database.
ENV['SCHEMA'] = 'db_public/schema.rb'
ENV['DB_STRUCTURE'] = 'db_public/structure.sql'
Rails.application.config.paths['db'] = ['db_public']
Rails.application.config.paths['db/migrate'] = ['db_public/migrate']
Rails.application.config.paths['db/seeds'] = ['db_public/seeds.rb']
Rails.application.config.paths['config/database'] = ['config/database_public.yml']
end
namespace :db do
scope_name = 'db'
# for all db tasks ...
Rake.application.tasks.find_all{|t| t.name.starts_with?(scope_name)}.map{|t| t.name[(scope_name.size+1)..-1] }.each do |taskname|
task_to_run = Rake::Task["db:#{taskname}"]
if description = task_to_run.comment
description.gsub!('db:','public:db:')
description.gsub!('db/','db_public/')
description.gsub!('database.yml','database_public.yml')
end
desc description
task taskname => :set_custom_db_config_paths do
task_to_run.invoke
end
end
end
end