Rails migration with a different user than regular connections - ruby-on-rails

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.

Related

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.

How to configure database.yml for production

I would like to deploy my application via Dokku to a VPS.
Putting together the dokku-postgres documentation and the relative, scarce internet documentation on the matter (one at GitHub), it seems necessary to configure database.yml to use the url environment variable url: <%= ENV['DATABASE_URL'] %>
Since I could not find any other sources of information, I wonder how database.yml should be configured, and how Rails will connect to the postgres service created with Dokku.
For instance, taken for granted that linking url to the DATABASE_URL variable is necessary, will this be enough to establish a connection between my Rails application and the postgres service or would it be still necessary to use a username and a password? In the latter case, what username and password am I expected to use?
Below is how at present my database.yml looks like.
default: &default
adapter: postgresql
encoding: unicode
pool: 5
username: asarluhi
development:
<<: *default
database: fireworks_app_development
test:
<<: *default
database: fireworks_app_test
production:
<<: *default
database: fireworks_app_production
pool: 25
username: fireworks_app
password: <%= ENV['FIREWORKS_APP_DATABASE_PASSWORD'] %>
This file was created as it is (apart from a higher pool size for production) when I created the application. How would you suggest to edit the production section?
The dokku-postgres documentation states that the following (and nothing else) will be set on the linked application by default:
DATABASE_URL=postgres://postgres:SOME_PASSWORD#dokku-postgres-lolipop:5432/lolipop
In place of the lollipop postgres service example, I would use fireworks_app_production to match the name of the database in database.yml
Are username and password still necessary after pointing url to the DATABASE_URL variable? Am I expected to add or remove anything else?
You don't need to worry about the database.yml with dokku, just upload your app to the server, let's use "fireworks" as the name for example on this.
when you upload the first time the app, this is created automatically so you don't need to create it.
then you install the postgres plugin and run
# that will create the container for the database
$ dokku postgres:create fireworks
# and then you link both, the app with the database
$ dokku postgres:link fireworks fireworks
you don't have to worry about anything else, with that dokku will connect this
then you just have to run db:migrate and everything is ready to work!

How to create new postgres user for a new Rails project?

I created a new rails project rails new devise_gem_app -d postgresql and changed config/database.yml to these:
default: &default
adapter: postgresql
encoding: unicode
username: devise_gem_app
password: devise_gem_app
host: localhost
development:
<<: *default
database: devise_gem_app_development
test:
<<: *default
database: devise_gem_app_test
But I don't know how to connect the user to this batabase
I create a user like this: createuser devise_gem_app -W set it as a super user and I set password to: devise_gem_app.
But when I try rake db:migrate I get:
PG::ConnectionBad: FATAL: password authentication failed for user "devise_gem_app"
FATAL: password authentication failed for user "devise_gem_app"
I even chenged last line of pg_hbf.conf to:
#local replication postgres trust
... and nothing ...
I know this should be easy but I just don't see what am I doing wrong.
I'm not sure what the createuser command is doing, but you could always set the password for the devise_gem_app user directly in postgres.
ALTER user devise_gem_app WITH password 'devise_gem_app';
create user user_name with password 'password' createdb;
And in pg_hbf.conf file
#Database administrative login by Unix domain socket
local all postgres peer
In the end I ended following this tutorial: http://www.cyberciti.biz/faq/howto-add-postgresql-user-account/
But I am upset that it seems rails don`t support, creating new users for new projects db, which seems to be common practice.

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.

Using an existing database of another Rails application in a new Rails application

I'm new to Rails. I had created a Rails application earlier and also collected a few data records in the development database. Suppose, I create a new Rails application and I prefer to use the existing development database of the 1st Rails application in my newly created Rails application, how do I do that?
Just change the file config/database.yml and set the database name.
your database.yml should look like this:
development:
host: localhost
adapter: mysql
database: your_database_name [just the name, not the path]
username: your_username
password: your_password
test:
...
production:
...
You need to change the database name in the database.yml file.
The seconnd problem you run into is migrations.
I would copy the migrations form your previous application over so that you maintain migration integrity with version numbers and rolling back if that is needed.
Also, if you are seeing development.locs - that locs refers to the table_name, which in restful context is usually also coincidentally the name of the controller.

Resources