Testing a Rails Application with Multiple Databases - ruby-on-rails

I have a rails application which uses two databases in production environment, Users and Process. The Users model uses this customized ActiveRecord class:
class UserActiveRecord < ActiveRecord::Base
establish_connection "#{Rails.env}_users_db"
end
class User < UserActiveRecord
...
Notice that the connection to a specific database is established depending on the environment. To simplify things, in the testing environment I have a single database with all the tables from the two production databases, and my database.yml file looks something like this:
test:
adapter: postgresql
database: db_test
host: localhost
pool: ...
timeout: ...
username: ...
password: ...
test_users_db:
adapter: postgresql
database: db_test <--- Notice that this is the same database only in test env
host: localhost
pool: ...
timeout: ...
username: ...
password: ...
The application runs fine in production, but when I run any test that refers to the User class, the test blocks at the exact point where User is used and nothing happens, it doesn't show any error, it doesn't exit, it just keeps waiting.
I double-checked and the table USERS exists in the test database, in fact if I delete it manually I get the error that the table doesn't exists and when I create it again I get the same behavior reported in the previous paragraph.
I don't have a clue why this is happening, any idea on how can I solve this issue? or how can I debug it so that I can get to the root of the problem? If it helps, I'm using Ruby 1.9.3, Ruby on Rails 3.2.19 and PostgreSQL 9.3.5; any additional details will be posted as required.

Have you tried explicitly stating that it's the same database? Try editing your database.yml file to look like this:
test: &default_test
adapter: postgresql
database: db_test
host: localhost
pool: ...
timeout: ...
username: ...
password: ...
test_users_db:
<<: *default_test

Related

Rails migration with a different user than regular connections

How can I connect to the DB with a different user when running rails migrations?
The use case is to create a different Postgres user for migrations than that used to run the webserver. Whereby the regular webserver DB user is limited to CRUD for data, but not have grants or abilities like DROP etc.
In order for that to happen, I need Rails migrations to run with a different user with full Create and Drop table access. (Creds could live in the Rails encrypted credentials file, but storing them in ENV on server is probably fine).
So, to be clear, setting up the users is not a problem, I can do all that. I just want to know if there is a best-practice way to change the user/creds used by rails db:migrate
You can create a new environment which has its own database user configured in config/database.yml. Example:
default: &default
adapter: postgresql
database: dev_db_name
username: dev_user_name
password: dev_password
development:
<<: *default
production:
<<: *default
database: production_db_name
username: production_user_name
password: production_user_password
migrations:
<<: *default
database: production_db_name
username: migration_user_name
password: migration_user_password
So when you run migrations you have to specify the new environment:
RAILS_ENV=migrations rake db:migrate
IMPORTANT: When create a new environment be sure that you complete this required steps:
Create a new config/environments/YOUR_ENVIRONMENT.rb file
Create a new database configuration entry in config/database.yml if your application uses database
Create a new secret key base entry in config/secrets.yml for apps on Rails 4.1 and higher
More information click here
You can set the database connection through ENV["DATABASE_URL"]. This takes precedence over and is merged with over any settings in config/database.yml:
DATABASE_URL=postgresql://localhost/some_other_database?username=max&password=p4ssw0rd rails db:migrate
If you want to do anything more advanced like using the encrypted credentials to store the password I would recommend writing a custom rake task.

Rails 6: why is it appending a number to the db name during model testing in a multi-db app?

I have the following multi-db setup in my rails 6.0.2.2 app:
development:
primary:
<<: *default
database: myapp_development
migrations_paths: db/migrate/primary
other:
<<: *default
database: other_development
migrations_paths: db/migrate/other
When I try a run a model test for models in either db, I get
Mysql2::Error::ConnectionError: Access denied for user 'my_user'#'localhost' to database 'myapp_test-3'
For each test, it appends a different number to the db name. The db user my_user does have access to the myapp_test db, but that obviously doesn't help when rails is adding a hyphen and an integer to the db name.
I've searched everything I can think of, but can't find any info.
Appreciate any info or suggestions (and apologies if I've missed something obvious)...
Check parallel testing in Rails 6. https://edgeguides.rubyonrails.org/testing.html#parallel-testing. That's why rails creates multiple DBs.

Read data from MS SQL server Database in rails ubuntu

I want to read data from MS SQL server
and perform some operations and store it in my mysql database (two databases are involved here one is external for which i only have read access);
I have established the connection with MS SQL server with tinytds and activerecord-sqlserver-adapter , but when i run User.first or User.find command on console its returning empty object( #< machinerawpunch > )
And i m establishing connection in my model class. I created 2 different models one is for MS SQL table and other is my rails mysql which is normal.
My model class is here
class MachineRawPunch < ActiveRecord::Base
ActiveRecord::Base.establish_connection :savior721
self.table_name = 'machinerawpunch'
end
My database.yml file is
savior721:
adapter: sqlserver
mode : dblib
dataserver: 192.68.1.2\SQLEXPRESS
database: savior721
username: user
password: user
default: &default
adapter: mysql2
encoding: utf8
pool: 5
username: root
password: root
socket: /var/run/mysqld/mysqld.sock
development:
<<: *default
database: assigment_app_development
test:
<<: *default
database: assigment_app_test
Please help me find the right way to access SQL server.That is i dnt want an empty array of object i need data which i can manupulate.A way which would return some thing like this
#
The way I normally do this is to synchronize data in a rake task.
so for example in lib/tasks/import_legacy.rb
namespace :admin do
def connect_legacy_db
require 'tiny_tds'
config = Rails.configuration.database_configuration['legacy']
TinyTds::Client.new :host=>config['host'], :username=>config['username'], :password=>config['password'], :database=>config['database']
end
desc "import all users from existing legacy db"
task :import_all_users => [:environment ] do
start=Time.now
puts "Starting user import at #{start}"
client = connect_legacy_db
# then my queries / transforms here such as
query="EXEC sp_user_migration;"
res = client.execute query
res.each do |row|
User.create name: row['username']
end
end
end
and my database.yml has the config for the legacy in there. I pulled the connect_legacy_db out to a method since it gets called from most of the tasks in there to sync various things over to the rails app. My existing database doesn't come close to rails conventions, it was easier to just write stored procs to handle the data migration tasks, and use TinyTDS directly as opposed to the activerecord-sqlserver-adapter stuff.
okay guys thanks for answering, and sorry for addressing this late;
but the bug was with gem activerecord-sqlserver-adapter it wasn't working well with rails 4.
after switching to rails 3.2, all was working properly.

How do I use an Existing Database in my Rails Tests?

I have a postgreSQL database with sample users, content and other data. How can I use it as my test database?
The tests will create new data in it, so I want to be able to easily reset it before each run of tests. Is there an easy way to convert a database into a format that can be used to easily re-create it?
This is the bad Idea to do but you can do this by changing config/database.yml
as
development:
adapter: postgresql
encoding: unicode
database: development_db
pool: 10
username: username
password: password
host: localhost
test
adapter: postgresql
encoding: unicode
database: test_db #change this db name to your development_db or whatever you want to use is test environment
pool: 10
username: username
password: password
host: localhost
Change Test environment database to which you want to use(database with sample users)
Note: If you want re-use original database again then I would suggest take backup of database with sample users then use this in test environment
If your data is not too complex, I would use fixtures for the job. The test database is rolled back after every test which can slow down your tests considerably when your test suite grows and your database must be prepopulated before every test.

Database not visible

I am trying to switch database from SqLite3 to Postgresql. My site connects to database in db/development but I can't see that file there. This is my database.yml:
development:
adapter: postgresql
database: db/development
pool: 5
timeout: 5000
username: user
When I create new database with createdb -O rolename dbname I don't see that database anywhere. I downloaded Navicat to browse my database but I can't find it.
I created a new migration after I configured app to use postgresql and it successfully migrated to that database. The problem is I can't see it anywhere. How can I insert data to database or open in in GUI if I don't see it anywhere?
When I run psql -U user db/development nothing happens.
When you're using PostgreSQL, the database: should be a simple database name, not something that looks like a filename. You should probably have something more like this:
development:
adapter: postgresql
database: appname_development
pool: 5
timeout: 5000
username: user
where appname is some sort of name for your application.
PostgreSQL doesn't use a simple file in your Rails directory tree to hold the database, PostgreSQL (and MySQL and SQL Server and ...) will use a collection of files off somewhere in its own directory and you generally shouldn't worry about where they are or what their structure is. If you want to dump the database for backup purposes then you'll want to use pg_dump.
You must have to provide host and port too.
adapter: postgresql
host: < host > # HOST
port: < port > # Port
database: < database name > # Database Name
username: < user_name > # User Name
password: '< password >' # Password
Default port of postgres will be 5432.

Resources