Deploy MySQL database on Heroku with Ruby on Rails - ruby-on-rails

I am trying to deploy a Rails project on Heroku. My Rails application uses mysql2.
I have tried using the taps gem but its not working. I get the following error when I run the command taps server mysql://root#localhost/heroku_ex tempuser tempass:
Failed to connect to database: Sequel::AdapterNotFound -> LoadError: cannot load such file -- mysql
Is there any way to deploy my application on Heroku? I would prefer to only use free add-ons if possible.

There are a few moving parts here.
First of all, Heroku doesn't support MySQL by default. If you want to use MySQL instead of PostgreSQL you will have to provision an add-on that provides it. There are currently at least two add-ons that provide MySQL or MariaDB¹ support with a free tier².
Next, Heroku doesn't run database servers on localhost. How can you handle different database configurations between your development machine and your Heroku server?
One strategy that is endorsed by Heroku is to store configuration in the environment. Following this model lets you alter your application's configuration by modifying environment variables instead of editing files. Luckily, Rails appears to override config/database.yml with configuration from the DATABASE_URL variable by default, so this approach should be a good fit.
Very often database add-ons will automatically set an environment variable for you. For example, the JawsDB Maria add-on sets JAWSDB_MARIA_URL when it is provisioned. This isn't the variable that Rails looks for, so you'll either have to tell Rails to look for JAWSDB_MARIA_URL instead of DATABASE_URL or manually set DATABASE_URL to contain the same URL that JawsDB provides in JAWSDB_MARIA_URL.
¹MariaDB is a fork of MySQL that aims to be fully-compatible.
²Note that the free tier may be quite limited, e.g. by only providing 5MB of storage. You may have to upgrade to a paid database tier as you continue to develop your application.

I have solved this by adding the pg gem in production and mysql2 in development environment.
group :development, :test do
gem 'mysql2'
end
group :production do
gem 'listen', '~> 3.0.5'
gem 'pg'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end

Related

Why postgres is not used in development?

I have encountered this in my Gemfile while learning ruby on rails:
group :development, :test do
gem 'sqlite3', '~> 1.4'
group :production do
gem 'pg'
So far I have understood that sqlite3 is not a production-ready database as it does not support multiple users to write the database at the same time. In this case, why don't we just use postgres in development?
There is no reason you can’t. It just requires additional configuration. It’s actually best practice to use the same database in development and production. SQLite is included for ease of use, and would probably fine for a lot of applications. But SQLite cannot be used on Heroku and some other hosting platforms. So you are better off setting up Postgres on your local machine for development in my opinion.

Detecting lack of gems in production

I do bundle install --without development test before my RoR application working in production because I want to remove gems only used in development or test, but the other day, this caused the problem.
I wrote some code and it works in development, but it contained module provided by the gem, which was installed as development gem's dependence. I used unintentionally so I cannot noticed by deployment failed. So I want to detect it. I'm using CI, so maybe I can notice if I do same bundle install as in production and something rails kicked, but if I do so, CI will take a long time so I don't really want to. I'd love to hear what you think.
edit: I think you haven't got my point yet, so let me explain it again.
for example, my Gemfile is like below;
ruby '2.5.7'
gem 'rails', '5.2.2.1'
gem 'pg', '>= 0.18', '< 2.0'
gem 'puma', '~> 3.11'
...
group :development, :test do
gem 'overcommit'
gem 'rails_best_practices'
gem 'rubocop' # <- this gem also install unicode_display_width(which has `Unicode::DisplayWidth`) as dependency
end
group :development do
gem 'brakeman'
gem 'debase'
gem 'rack-mini-profiler', require: false
gem 'ridgepole'
gem 'ruby-debug-ide', '0.6.0'
...
end
group :test do
gem 'simplecov'
...
end
and I used Unicode::DisplayWidth in my application because I totally thought it was the library ruby originally has(like csv). I don't want to do something like this again, but I may do carelessly, so I want to detect it.
It's not really clear what your problem is from your description. But have a look at bundle list to view installed gems https://bundler.io/man/bundle-list.1.html
Also, try bundle config and if you see any without's that you were not expecting, you can run bundle config --delete without to remove them.
I'm going to try and paraphrase what I think you're asking based on your updated question:
You want your CI pipeline to detect if you used a library in your code that wasn't made available via bundler*, but you don't want to slow your CI pipeline down with another bundle install command.
If that's the case, we have 3 separate pipelines/processes that we use:
CI/CD pipeline on Semaphore to run our automated tests. This pipeline won't catch the type of error described above
Separate pipeline using Heroku's review app feature which builds a "live" application using dummy/seed data, but production-like settings (e.g. bundle install --without development text). This may catch the type of error described above; you may have to use the review app to trigger the error and sometimes we don't
We also have a separate staging environment where user testing occurs, which is also production-like. This is where that type of error should definitely be identified (because we have users test features here by using the site)
This has been a common strategy at a number of projects I've worked on for catching this kind of error before it deploys to production.
* Because bundler in production is run bundle --without development test

How to run ruby on rails apps with different versions of rails?

I have about 3 apps on a Windows Server 2012 and all of them are different versions of rails. So far, I can run locally the app with the latest version of rails, but not the other two, which were deployed from Heroku. I wanted to make changes locally before I push them to Heroku but no luck. Is there any reference to that or is this even possible? thanks a lot!
Your problem is that you are trying to use sqlite with Heroku. Heroku requires using 'postgres' as the database
change the gemfile to the following
group :development do
gem 'sqlite3'
end
group :production do
gem 'pg'
end
And then change your database.yml file to this
adapter: postgresql

Switching Rails app from SQLite to Postgres for local development

I have a little Rails app that is deployed on Heroku. They require a Postgres database, which was not a problem to switch from SQLite3 on their side, but now I can't develop locally without pushing to Heroku every time I want to see changes. I downloaded and installed all of the Postgres assets including the little MenuBar app that keeps a server running and have been all over documentation. Any help?
try this
write in your gemfile
group :development do
gem "sqlite3"
end
group :production do
gem 'pg'
end
when you are working on development mode then it used sqlite3
and while you are working on production mode then it used pg

Ruby Gemfile & database adapters

I am developing on an open source rails application and as a rails 3 project, it includes a Gemfile. The application is also dependent on a database adapter for active record. I can specify a specific adapter (like gem 'sqlite3') within the Gemfile but this is not what I want to do. I advertise the app as beeing compatible with all the adapters active record is compatible with. Is there any way to specify that the app depends on a single database adapter (out of a selection) but that one is sufficient? Something like
any_of do
gem 'sqlite'
gem 'mysql'
etc.
end
Thanks for any help or suggestions how to approach the problem differently.
I just recently installed something that generated an error, until I realized how they handled this.
group :postgresql do
gem 'pg'
end
group :mysql do
gem 'mysql2'
end
and then when you run bundler:
bundle install --without postgresql

Resources