Passing ENV variables to database.yml in Rails - ruby-on-rails

Here is my database.yml config:
development:
adapter: ibm_db
username: "username"
password: "password"
database: '*LOCAL'
schema: <%= ENV['CA_SCHEMA'] %>
ibm_i_isolation: 'none'
Here is my initializer:
module Ca2eModelExtractor
class Application < Rails::Application
config.before_configuration do
ENV['CA_SCHEMA']= 'XAMDL'
end
end
end
After running rails c I did ENV['CA_SCHEMA'] and saw XAMDL as an output, so it works as expected. But when I run ActiveRecord::Base.configurations, I got a hash, where schema is nil. Any ideas?

Related

Separate read/write configuration/setup for Rails 7 application

rails 7
AWS Aurora RDS Cluster with one write endpoint and one read endpoint
I would like to configure my Rails application to use one endpoint to write and one endpoint to read for the production environment, and a single endpoint for reading/writing in the test environment.
Reading through the documentation, it seems as what I need to do, is that I need to do the following (assuming a production .
In /config/database.yml:
production:
primary:
database: my_primary_database
username: root
password: <%= ENV['PRIDUCTION_ROOT_PASSWORD'] %>
adapter: mysql2
primary_replica:
database: my_primary_database
username: root
password: <%= ENV['PRIDUCTION_ROOT_PASSWORD'] %>
adapter: mysql2
replica: true
test:
database: my_test_database
username: root
password: <%= ENV['TEST_PASSWORD'] %>
adapter: mysql2
Note: the documentation mentions that the username for the writers and replicas should be different, but the AWS Aurora cluster will not allow me to do that. Is this a recommendation or a must?
And this is what I should have in my /app/models/application_record.rb:
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
if Rails.env == 'production'
connects_to database: { writing: :primary, reading: :primary_replica }
end
end
Then, run the following command:
rails g active_record:multi_db
Which will generate the file: config/initializers/multi_db.rb and inside that file do:
Rails.application.configure do
if Rails.env == 'production'
config.active_record.database_selector = { delay: 2.seconds }
config.active_record.database_resolver =
ActiveRecord::Middleware::DatabaseSelector::Resolver
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end
end
Am I missing anything, or do I need to add the following to config/environments/production.rb?
config.active_record.writing_role = :default
config.active_record.reading_role = :readonly
Anything else?

make rake db:create setup another database besides development, test or production

I'm using rails 4.2 and trying to configure (in a already established application) the Audited Gem following this second database approach.
My config/database.yml file was as follows:
default: &default
adapter: mysql2
pool: 5
timeout: 5000
development:
<<: *default
host: <%= ENV["MYSQL_HOST"] %>
username: <%= ENV["MYSQL_USER"] %>
password: <%= ENV["MYSQL_PASSWORD"] %>
database: <%= ENV["MYSQL_DATABASE"] %>
test:
<<: *default
host: <%= ENV["MYSQL_HOST"] %>
username: <%= ENV["MYSQL_USER"] %>
password: <%= ENV["MYSQL_PASSWORD"] %>
database: <%= ENV['TEST_ENV_DB'] %>
And I intend to make it work for another db, besides development, test or production. However the task rake db:create only creates my development and test database. Is this possible to accomplish in my rails version?
audition:
<<: *default
host: <%= ENV["MYSQL_HOST"] %>
username: <%= ENV["MYSQL_USER"] %>
password: <%= ENV["MYSQL_PASSWORD"] %>
database: <%= ENV["AUDITION_DATABASE"] %>
Note the new name for audition database
if you want to read/write to a seconds database in rails < 6
create a module
module AuditionConn
def self.included(base)
base.class_eval do
if Rails.env == 'development'
establish_connection "audition-development" # database.yml
else
establish_connection "audition-production" # database.yml
end
end
end
end
then include it in any model you want to read/write from/to auditions database
class AuditionDBModel < ActiveRecord::Base
include AuditionConn
end
migration for second database
def up
AuditionDBModel.connection.create_table ... do |t|
...
AuditionDBModel.connection.change_column ...
end
I think you want to create a new environment call audition, Right?!.
Clone an existing environment file for instance, config/environments/test.rb and rename it config/environments/audition.rb
Add a new configuration block in config/database.yml for your environment.
Update any other configuration file you might have under the config folder with your new environment, some gems need to config it.
Now you can start the server
rails server -e audition
I think this may help you:
create another model for audit:
class AuditModel < ActiveRecord::Base
connects_to database: { writing: :audit_db, reading: :audit_db}
end
or
ActiveRecord::Base.establish_connection(
adapter: "mysql2",
host: "localhost",
username: "myuser",
password: "mypass",
database: "somedatabase"
)
for details:
https://guides.rubyonrails.org/active_record_multiple_databases.html
https://edgeapi.rubyonrails.org/classes/ActiveRecord/ConnectionHandling.html

Heroku - Rails 6 - multi-database

rails: gem "rails", "6.0.0.rc2"
I have multiple databases. None are replicas (I am reading and writing in all 3):
Before rails 6, I used multiverse gem and everything looked fine.I followed rails 6 and multiverse change to rails 6 docs. But I cannot run db:migrate in Heroku, even though, everything works perfectly locally.
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
establish_connection :primary
end
.
class ObsRecord < ActiveRecord::Base
self.abstract_class = true
establish_connection :obs
end
.
class AbcRecord < ActiveRecord::Base
self.abstract_class = true
establish_connection :abc
end
database.yml
staging:
primary:
<<: *default
adapter: postgresql
url: <%= ENV['DATABASE_URL'] %>
username: <%= ENV['DATABASE_USER'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
obs:
<<: *default
adapter: postgresql
url: <%= ENV['OBS_DATABASE_URL'] %>
username: <%= ENV['OBS_DATABASE_USER'] %>
password: <%= ENV['OBS_DATABASE_PASSWORD'] %>
migrations_paths: db/obs_migrate
abc:
<<: *default
adapter: postgresql
url: <%= ENV['ABC_DATABASE_URL'] %>
username: <%= ENV['ABC_DATABASE_USER'] %>
password: <%= ENV['ABC_DATABASE_PASSWORD'] %>
migrations_paths: db/abc_migrate
rails db:migrate shows nothing, as if there are no migrations but when I run rails c I see the following error. And yes, I am sure the lates code is pushed.
heroku restart is not helping
Heroku error:
Traceback (most recent call last):
102: from /app/bin/rails:4:in `<main>'
101: from /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0.rc2/lib/active_support/dependencies.rb:322:in `require'
.
.
4: from /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0.rc2/lib/active_record/connection_handling.rb:50:in `establish_connection'
3: from /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0.rc2/lib/active_record/connection_handling.rb:180:in `resolve_config_for_connection'
2: from /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0.rc2/lib/active_record/connection_adapters/connection_specification.rb:140:in `resolve'
1: from /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0.rc2/lib/active_record/connection_adapters/connection_specification.rb:219:in `resolve_connection'.
.
/app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0.rc2/lib/active_record/connection_adapters/connection_specification.rb:251:in `resolve_symbol_connection': The `abc` database is not configured for the `staging` environment. (ActiveRecord::AdapterNotSpecified)
Available databases configurations are:
default
prod_uat_default
development
test
staging
uat
production
^^ I am expecting primary, abc, and obs under staging.
Also, rails -T doesn't show anything regarding to my second and 3rd database
Used the 6.0-stable version and it worked:
gem "rails", github: "rails/rails", branch: "6-0-stable"

Populate .yml file dynamically in Ruby on Rails

I want to populate my .yml file in config folder dynamically when my server is loading.
The following is an example of my .yml file
# Configuration Credentials
development: &development
user: "***"
password: "***"
test:
<<: *development
non-prod:
user: "***"
password: "***"
production: &production
user: "***"
password: "***"
I want to set the value for each key in the form of embedded ruby like this:
development: &development
user: <%= get_value_for(user) %>
password: <%= get_value_for(password) %>
I want to load the .yml file when the server is about to run.
I want to know where should I define the get_value_for method so I can call it inside my yml file? (probably in application.rb but I do not know how exactly)
Create a custom class and define the method their. Then require the class inside config/application.rb
# app/global/database_details.rb
class DatabaseDetails
def self.get_value_for(user)
end
end
Inside config/application.rb
require_relative '../app/global/database_details'
module AppName
class Application < Rails::Application
end
end
Inside config/database.yml
development: &development
user: <%= DatabaseDetails.get_value_for(user) %>
password: <%= DatabaseDetails.get_value_for(password) %>

Set default database connection Rails

My rails app has its own MySql database (and requires the mysql2 gem) but also needs to connect with an external MongoDB database for one particular model (and so I've included mongoid and bson_ext in the Gemfile). Now when I try to generate a migration for a new model, it tells me that
$ rails g migration CreateLocations
error mongoid [not found]
When I generated the Location model it included Mongoid::Document, so Rails obviously thinks it is using the external database as my primary datastore.
databse.yml:
development:
adapter: mysql2
encoding: utf8
reconnect: false
database: associalize_development
pool: 5
username: root
password:
socket: /tmp/mysql.sock
mongoid.yml:
development:
host: pearl.mongohq.com
port: 27019
username: asfasdf
password: sadfasdf
database: app4574678
test:
host: pearl.mongohq.com
port: 27019
username: asdfadhasdfa
password: hadsadfas
database: app4574678
production:
host: pearl.mongohq.com
port: 27019
username: asdfdfsasda
password: afdasdfdasdf
database: app4574678
UPDATE
Model that uses Mongo
class ExternalMongoModel
include Mongoid::Document
field :title
field :long_title
field :deal_type
field :merchandise_type
field :market_id
field :market_name
field :market_location, type: Array
field :featureType
field :country_code
field :subtitle
field :offer_ends_at
field :price
field :value
field :merchant_type
field :content
field :merchant
index(
[[:division_latlon, Mongo::GEO2D]], background: true
)
end
Add this to the Application block in config/application.rb:
config.generators do |g|
g.orm :active_record
end
(found here)
If you don't want to change the config/application.rb you could use this while generating the model:
rails generate active_record:migration
If you change the application.rb file, to invoke a mongoid generator, say for a model 'contacts', one would use:
rails g mongoid:model contacts
(solution link)
First check the below block is present in config/application.rb file in your rails application
config.generators do |g|
g.orm :active_record
end
If not add then, or else you can run
rails g active_record:migration

Resources