Rails 5 - ENV DATABASE_URL - specify encoding and collation - ruby-on-rails

Our database.yml is added to .gitignore so devs can customize local environments and we plan to use ENV['DATABASE_URL'] for production servers. For default setup, this works. However, we need to configure encoding and collation to utf8mb4.
encoding: utf8mb4
collation: utf8mb4_unicode_ci
I tried padding it to query parameters, like the ?pool=5 example in the docs, but it doesn't seem to work.
DATABASE_URL=mysql2://user:passwd#host:port/dbname?encoding=utf8mb4&collation=utf8mb4_unicode_ci
The tables created are still using the default encoding/collation so I assume the parameters doesn't work. Is there any way I could configure this by any other methods? Encoding and collation is the same for all environments.
Requirement is that dev environment can have a file with a config whereas prod should have no special file added, it should only use ENV variables. Maybe add this to one of the files inside config dir like application.rb or other files?
Thanks in advance.
PS: I'm new to Rails and Ruby (1 week) since I'm coming from PHP/Python.

You shouldn't specify any of the configuration options in the ENV variable. You should keep it clean and specify these options in database.yml file:
production:
encoding: utf8mb4
collation: utf8mb4_unicode_ci
pool: 5
The way it works is that rails takes what it can from the DATABASE_URL, and then applies options configured in database.yml for specified environment. If you want to learn more, follow this link: https://devcenter.heroku.com/articles/rails-database-connection-behavior#rails-4-1-and-beyond

Related

rails app running multiple times on production with different configurations

I want to run the same rails app several times with a few configuration differences on the same server. Each app must have its own:
database
ports
cookie_store key(not sure if needed)
secret_key_base
Let's say I want to run the same code multiple times to service different cities:
newyork.myapp.com and boston.myapp.com. I wonder what would be the best way to store and use the different configurations.
Use environments:
Add a file to config/environments, one for each site you want to host. Name it something along the lines of 'production_[city]', replacing [city] with the city name. Copy the production.rb file contents into each.
in config/database.yml find the 'production' block of yml and duplicate it once for each site you want to host. Rename the root node of each block to production_[city], matching the filenames above. For example:
production_ny:
adapter: mysql2
username: my_user
password: my_pa$$w0rd%&*#
database: production_ny
This takes care of the database settings per app.
Assuming Rails 4, your secret key base will be in config/secrets.yml under an environment node, as per config/database.yml so just add an entry per site:
production_ny:
secret_key_base: xxxxxxxx1111111122222223333333344444444...
All sites will need an end-point. Using a different domain for each would give you separate cookies and sessions for free. Or you could go the subdomain route:
http://guides.rubyonrails.org/configuring.html#deploy-to-a-subdirectory-relative-url-root
tldr:
In your config/environments/production_ny.rb:
config.relative_url_root = "/ny"
for example. Then set up your webserver to handle subdirectories. You may need to add a path to cookies in order to scope them to the virtual directory. Just use:
Rails.configuration.relative_url_root
Ports, again, will have to be set up at the webserver level. (Apache, nginx, etc.)
To see if it all works, try this in the command-line:
RAILS_ENV=production_ny bundle exec rails s
This should start a development style webserver for you to access, but use the production_ny environment.
You will need to create and set up your database as normal - create, migrate, seed.
The final step is setting the RAILS_ENV environment variable to production_[city] per app using your web server. The steps to do this will depend on your technology choice.

Heroku with AWS RDS: Are details in database.yml needed?

We're running a Rails app on Heroku and have it connected to a database on Amazon RDS. It works fine, the security zone is configured and the app is live.
Heroku requires you to provide a Database URL in the format of
mysql2://user:pass#rdsinstance.com/database
Since we're specifying the DB info in the add-on, what do we need to provide in the database.yml file, if anything?
Would the following suffice, or do we need even less than that? Maybe just the adapter name?
production:
adapter: mysql2
encoding: utf8
reconnect: false
pool: 5
Heroku automatically replaces the content of any database.yml file on deploy with the value of the shared database, normally stored in the SHARED_DATABASE_URL config variable.
I don't know if it's save to override that value. If you do it, you should be able to connect to the database from Rails without any additional effort.
If your app is working fine and you are just wondering what you need to write inside the default database.yml file, then you can put in whatever you want, Heroku will replace it in any case on deploy.

How do I handle database.yml development mode configuration with multiple develpers?

what's the standard way of dealing with development mode database config for database.yml when there are multiple developers on a project?
Should all devs have the same database setup? Is that a smart requirement?
Or should there be some type of gitignore and symlinking taking place? I did this and after branching, the database.yml disappeared :(
I've also come up with an erb solution that seems to work well enough, but not sure if there will be unintended consequences. The following will allow devs to sed environment variables in their bash_profile in case they have a different local setup than the default. This will allow our database.yml file to stay in git.
development:
adapter: postgresql
database: <%= ENV['DEV_DB_DATABASE'] || 'app_development' %>
username: <%= ENV['DEV_DB_USERNAME'] || 'postgres' %>
password: <%= ENV['DEV_DB_PASSWORD'] || '' %>
host: localhost
encoding: UTF8
Add database.yml.sample file to the rails app, also add database.yml to the .gitignore. This way all developers can have different database setups.

Ruby on Rails use of environment variables

I want to use in my code (in views as well) variables like:
ENV['SERVER_URL1']
And want them to be different for diffident environments (prod, dev, test)
Were and how should I set them up?
Is this (using ENV vars) a right way to configure application for different environments?
about ENV['SERVER_URL'] - is it a standard variable? When does it becomes available.
I tried to set in different parts of application (application.rb, development.rb)
ENV['SERVER_URL1'] = 'http://localhost:4000/'
but it seems not to work.
When using Rails 4.1+, the new and preferred way to set ENV variables is to use the config/secrets.yml file.
Here is an excerpt from the 4.1 release notes
The secrets added to this file are accessible via Rails.application.secrets. For example, with the following config/secrets.yml:
development:
secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
some_api_key: SOMEKEY
Rails.application.secrets.some_api_key returns SOMEKEY in the development environment.
See the Upgrading Ruby on Rails guide on how to migrate existing applications to use this feature.
So you should set:
development:
SERVER_URL1: http://localhost:4000
production:
SERVER_URL1: http://my-domain.com

Ruby on Rails: How to set a database timeout in application configuration?

I'd like to set my database to timeout requests that do not complete within a set amount of time, in order to prevent outlier requests from monopolizing the entire application.
Is there anything I can add to my Rails configuration files in order to set this?
I tried to add a line I saw often online of timeout: 5000 to my database.yml, but that didn't seem to have any effect.
I tried to make calls to ActiveRecord::Base.connection.execute('set statement_timeout to 5000') in the environment.rb but that causes Rails to error out.
I'm running a Postgres database on Heroku, where I do not have direct database access, hence I cannot do this with database configuration directly. Even if I remotely execute that command from the Heroku console, they can restart my application at any time, and if this isn't re-executed as the application starts, my change gets lost.
database.yml:
defaults: &default
adapter: postgresql
encoding: unicode
pool: 5
min_messages: warning
variables:
statement_timeout: 5000
Got this working, just needed to include the line in environment.rb at the very end, rather than in the beginning or in the block.
Try this syntax:
SET statement_timeout = 5000;

Resources