Set default database connection Rails - ruby-on-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

Related

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

Passing ENV variables to database.yml in 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?

Connecting to multiple databases in ruby on rails

I have a ruby on rails application working fine and connected to a database. Now i want to connect to a different database from the same application. The data model can be exactly the same. In fact if i connect to the different database the application works fine. However I want to connect to two different databases. Is it possible in ruby on rails?
For multiple database connection, you need to add the following codes to the database.yml file. Here, I am giving the example of connecting two databases from a rails application
config/database.yml
development:
adapter: mysql2
database: db1_dev
username: root
password: xyz
host: localhost
development_sec:
adapter: mysql2
database: db2_dev
username: root
password: xyz
host: localhost
production:
adapter: mysql2
database: db1_prod
username: root
password: xyz
host: your-production-ip
production_sec:
adapter: mysql2
database: db2_prod
username: root
password: xyz
host: your-production-ip
Here I have used two databases for the development and production environment.
Now we need to connect the model to databases. When you are running your application in development and production mode, all the models will be mapped through the development and production db parameters those been mentioned in your database.yml. So for some model we need to connect to other database.
Lets assume that, we have two models User and Category. The users table is in db1_dev and db1_prod, the categories table in db2_dev and db2_prod.
Category model
class Category < ActiveRecord::Base
establish_connection "#{Rails.env}_sec".to_sym
end
Similarly, when you adding the new migration for the second database, need to add following code to it.
class CreateRewards < ActiveRecord::Migration
def connection
ActiveRecord::Base.establish_connection("#{Rails.env}_sec".to_sym).connection
end
def change
# your code goes here.
end
end
Hope it will work for you :) .
Use establish_connection to switch to a different database:
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
You can also pass a preconfigured environment from database.yml like so:
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['other_env'])
You can also set it for a specific model:
MyClass.establish_connection(...)
You might like to note that as of Rails 6 (2019), Rails has support for multiple primary databases!
https://guides.rubyonrails.org/active_record_multiple_databases.html
The database.yml file will now look something like this:
development:
primary:
database: primary_db
user: root
primary_replica:
database: primary_db
user: ro_user
replica: true
animals:
database: my_animals_db
user: root
migrations_path: db/animals_migrate
animals_replica:
database: my_animals_db
user: ro_user
replica: true
And then it's as simple as specifying in your model files:
class AnimalsModel < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :animals_primary, reading: :animals_replica }
end
class Dog < AnimalsModel
# connected to both the animals_primary db for writing and the animals_replica for reading
end
(These examples were taken from this helpful tutorial.)

rails and sqlserver encoding

I'm developing an aplication with mysql and sqlserver. sqlserver is used to connect to a legacy table.
here is my definition
development:
adapter: mysql2
encoding: utf8
reconnect: false
database: spvalores_development
username: secret
password: secret
pool: 5
host: 192.168.100.35
socket: mysql
port: 3306
sql_server_db:
adapter: sqlserver
database: SPPokerManager
dsn: DesaSqlServer
mode: odbc
username: sa
password: master
encoding: utf8
the gems i use:
gem 'activerecord-sqlserver-adapter'
gem 'ruby-odbc'
this is my model
class Client < ActiveRecord::Base
self.table_name = "dbo.LOB_CLIENTE"
self.primary_keys = :CASINO_ID, :CLIENTE_ID
establish_connection :sql_server_db
attr_accessible :CASINO_ID, :CLIENTE_ID, :CDNI, :CAPELLIDO, :CNOMBRES,:TIPODOCUMENTO_ID, :CNICKNAME, :CDIRECCION, :CTELEFONO, :CCELULAR, :CEMAIL, :COBSERVACIONES, :CLIENTEPERFIL_ID
attr_accessible :DFECHAINGRESO, :BIDENTIFICADO, :BACEPTAENVIOSMS, :IFOTO, :COLATIPOPREFERIDA_ID
attr_accessible :BACTIVO, :CNROJUGADOR, :CSEXO, :DFECHANACIMIENTO, :NACIONALIDAD_ID, :CEMAIL2, :CPATROCINADOR, :CPAISRESIDENCIA, :CPROVINCIARESIDENCIA, :CCIUDADRESIDENCIA
attr_accessible :DFECHAHORA_CESIONIMAGEN, :BFIRMA, :BJUGADORFRECUENTE, :DFECHAACTUALIZACION
def as_json(options={})
nick = self.CNICKNAME.force_encoding("ISO-8859-1").encode("UTF-8")
name = self.CNOMBRES.force_encoding("ISO-8859-1").encode("UTF-8") unless self.CNOMBRES.nil?
surname = self.CAPELLIDO.force_encoding("ISO-8859-1").encode("UTF-8") unless self.CAPELLIDO.nil?
{:CLIENTE_ID => self.CLIENTE_ID ,:CNICKNAME => nick ,:CAPELLIDO => surname ,:CNOMBRES => name, :CDNI => self.CDNI, :TIPODOCUMENTO_ID => self.TIPODOCUMENTO_ID }
end
end
i always get errors like this:
incompatible character encodings: ASCII-8BIT and UTF-8
the only way i solved is doing something like this
modelinstance.field.force_encoding("ISO-8859-1").encode("UTF-8")
There are a lot of field on that table. Beside, sure i will need to query other tables like this one.
Looking in the database properties the collation is Modern_Spanish_CI_AS
How i can configure rails to show and save property in the collation Modern_Spanish_CI_AS
Thanks in advance, hope to be clear
Well I finally solve the problem.
I need to use tiny_tds:
here is the explanation:
https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/wiki/Using-TinyTds

How to configure multiple database sources in a rails application

I would like to configure 2 database instances for a certain environment (say staging or production). The default rails new application just provides a single database instance how do I configure 2 database instances.
You can copy and past one of your existing configurations such as development. and rename it as you want so, in the database.yml:
development:
adapter: mysql2
encoding: utf8
reconnect: false
database:
pool: 5
username: root
password:
host: localhost
new_database:
adapter: mysql2
encoding: utf8
reconnect: false
database:
pool: 5
username: root
password:
host: localhost
Then in the models you create for this new connection add the following methods to the model, for example:
class Document < ActiveRecord::Base
self.table_name = "document" # this allows you to hide a non comforming table name behind the rails model it is NOT necessary for establish_connection to work
self.establish_connection "new_database" # notice there is no = when setting this value, strange, I know.
end

Resources