In a rails application, I have this code in pure ruby :
class LinkCreator
attr_accessor :animal
def initialize(animal:)
@animal = animal
end
de
It would be nice if you keep all database connections in database.yml
development:
adapter: mysql2
other stuff...
db_2:
adapter: mysql2
other stuff..
other_envs:
.....
Then create a class
class OtherDB < ActiveRecord::Base
establish_connection(:db_2)
end
From your controller you can access just like
OtherDB.table_name = "table_name"
OtherDB.first
Check my blog here http://imnithin.github.io/multiple-database.html
Try active_record_slave gem:
Ruby gem: active_record_slave
If you want to connect to postgres sql, you can use pg ruby gem & add the below code inside the block.
postgres = PG.connect :host => <host_name>, :port => <port>, :dbname => <database_name>, :user => <user>, :password => <password>
tables = postgres.exec(query)
tables.num_tuples.times do |i|
print tables[i]
end
To connect to mysql db inside a block, use mysql2 ruby gem & add the below code inside the block.
db = Mysql2::Client.new ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(<database_url>).to_hash
data = db.query(<<-SQL)
select * from students
SQL
print data
You can perform some queries within a block. First, define some module which will extend ActiveRecord, as below. This is a part of code used in production to change db connection per each request as well as to temporarily switch db to perform some queries within another database.
# RAILS_ROOT/lib/connection_switch.rb
module ConnectionSwitch
def with_db(connection_spec_name)
current_conf = ActiveRecord::Base.connection_config
begin
ActiveRecord::Base.establish_connection(db_configurations[connection_spec_name]).tap do
Rails.logger.debug "\e[1;35m [ActiveRecord::Base switched database] \e[0m #{ActiveRecord::Base.connection.current_database}"
end if database_changed?(connection_spec_name)
yield
ensure
ActiveRecord::Base.establish_connection(current_conf).tap do
Rails.logger.debug "\e[1;35m [ActiveRecord::Base switched database] \e[0m #{ActiveRecord::Base.connection.current_database}"
end if database_changed?(connection_spec_name, current_conf)
end
end
private
def database_changed?(connection_spec_name, current_conf = nil)
current_conf = ActiveRecord::Base.connection_config unless current_conf
current_conf[:database] != db_configurations[connection_spec_name].try(:[], :database)
end
def db_configurations
@db_config ||= begin
file_name = "#{Rails.root}/config/database.yml"
if File.exists?(file_name) || File.symlink?(file_name)
config ||= HashWithIndifferentAccess.new(YAML.load(ERB.new(File.read(file_name)).result))
else
config ||= HashWithIndifferentAccess.new
end
config
end
end
end
ActiveRecord.send :extend, ConnectionSwitch
Now you can use it as below:
ActiveRecord.with_db("db_connection_name") do
# some queries to another db
end
I use environment variables taken from Heroku's DATABASE_URL
to connect to different databases:
class Database
def self.development!
ActiveRecord::Base.establish_connection(:development)
end
def self.production!
ActiveRecord::Base.establish_connection(ENV['PRODUCTION_DATABASE'])
end
def self.staging!
ActiveRecord::Base.establish_connection(ENV['STAGING_DATABASE'])
end
end
e.g.:
Database.production!; puts User.all.map(&:name)
Database.staging!; puts User.all.map(&:name)
It might help to use an instance variable to store the connection. Something like this:
def connection
@connection ||= ActiveRecord::Base.establish_connection(
adapter: "mysql",
host: ENV["MYSQL_HOST"],
username: ENV["MYSQL_USERNAME"],
password: ENV["MYSQL_PASSWORD"],
database: ENV["MYSQL_DB_NAME"]
).connection
end
That way the existing connection is retrieved on future connection attempts, rather than establishing a new one.