【Rails】SQlite3から本番環境だけPostgreSQLに変更する方法をどこよりも優しく伝える！

# 目的
[Render.com](https://render.com/)というPaasを利用して本番環境にアップする際に、データベスはPostgreSQLが指定されていました。
RailsのデフォルトDBはSQlite3ですので、PostgreSQLに乗り換える必要があるということです。
本記事では、テストと開発環境はSQlite3のまま、本番環境だけPostgreSQLに変更する手順を記録します。

# 手順

## Rails newで新しいアプリを作成する
今回は最終的にRender.comにデプロイするところまで説明しますので、`Render_app`というアプリを作成します。

ターミナルにて
```terminal
$ rails new Render_app
...
$ cd Render_app
```

このタイミングで[GitHubにレポジトリを作成](https://qiita.com/ysk91_engineer/items/a87f95fbf76018963782)しておきます。

### 環境
私が作成したプロジェクトのバージョンは以下です。

```terminal
$ ruby -v
=> ruby 3.1.2p20

$ rails -v
=> Rails 7.0.4
```

## PostgreSQLを使う準備

### macにHomebrew経由でpostgreSQLをインストールする
Rubyを扱う方ならHomeburewはインストール済かと思いますが、一応インストール方法の参照元を置いておきます。
https://prog-8.com/docs/ruby-env

ターミナルにて`postgresql`の最新の安定版をダウンロードしましょう。

```
$ brew install postgresql
...

# 導入確認
$ psql --version
=> psql (PostgreSQL) 14.5 (Homebrew)
```

### PostgreSQLの初期設定
PostgreSQLをインストールしたら、使用するための初期設定をします。

#### データベースの初期化
まずは、データベースを初期化します。
```terminal
$ initdb /usr/local/var/postgres -E utf8
```

#### PostgreSQLの立ち上げ・停止
PostgreSQLの立ち上げ・停止は以下のコマンドでおこないます。
```terminal
# 立ち上げ
$ brew services start postgresql
==> Successfully started `postgresql@14` (label: homebrew.mxcl.postgresql@14)

# 停止
$ brew services stop postgresql
==> Successfully stopped `postgresql@14` (label: homebrew.mxcl.postgresql@14)
```

#### ユーザー設定
PostgreSQLを**立ち上げた状態で**ユーザー設定をしていきます。

```terminal
$ createuser -s -P <ユーザー名>
Enter password for new role: <パスワードを設定>
Enter it again: <サイドパスワードを入力>
```
このとき、入力したパスワードは表示されないので気をつけましょう。

ユーザー設定が完了したらPostgreSQLを停止します。

## RailsアプリにPostgreSQLを導入

下準備ができたら、RailsアプリにPostgreSQLを導入していきます。

### Gemfileの編集

SQlite3のgemを`development`と`test`環境に引っ越しさせます。
```diff_ruby:Gemfile
- # Use sqlite3 as the database for Active Record
- gem "sqlite3", "~> 1.4"

+ group :development, :test do
+   # Use sqlite3 as the database for Active Record
+   gem "sqlite3"
+   (略)
+ end
```
このとき、バージョンの指定を削除して常に最新版を使用するようにしました。

次に、本番環境にPostgreSQLを使用するように指定します。

```ruby:Gemfile
group :production do
  # Use PstgreSQL as the database for Active Record
  gem 'pg'
end
```

Gemファイルを編集したら
```
$ bundle install
```
します。

### 環境設定
使用するデータベースの設定を環境ごとに指定するために、環境設定をしていきます。

#### database.ymlを編集
データベースの設定は`config/database.yml`ファイルで指定します。
下記のように編集します。

**before**

```ruby:config/database.yml
# SQLite. Versions 3.8.0 and up are supported.
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem "sqlite3"
#
default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: db/production.sqlite3
```

↓**after**
```ruby:config/database.yml
default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

test:
  <<: *default
  database: db/test.sqlite

production:
  adapter: postgresql
  encoding: unicode
  pool:  <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  database: <任意のデータベース名>
  username: <任意のユーザー名>
  password: <%= ENV['DB_PASSWORD'] %> # .envで設定
```

#### 環境変数を設定
上で設定した`database.yml`ファイルはGitHubにアップされます。
このファイルの中に本番環境で使用するデータベースのアクセスパスワードを直接記入すると、不正アクセスが発生する可能性があります。
そこで、`.env`というファイルを作成し、大切な情報はそこに記入するようにします。
ymlファイルの最終行にあるRuby式`<%= ENV['DB_PASSWORD'] %>`は、`.env`ファイルから値を引っ張ってくる指示をしています。

.envファイルを作成する手順を記します。

まずは、本番環境用に`dotenv-rails`というGemファイルをインストールします。
```ruby:Gemfile
group :production do
  (略)
  # 環境変数の設定
  gem 'dotenv-rails'
end
```

```terminal
$ bundle install
```

プロジェクトフォルダ直下に`.env.production`ファイルを作成し、パスワードを記入します。
```ruby:.env.production
DB_PASSWORD = '<任意のパスワード>'
```
:::note warn
この時点では本番環境用のデータベースを作成していないので、パスワードは発行されていません。
とりあえず`.env.production`のファイルを作成するだけでOKです。
:::

「`database.yml`にパスワードを直接書かないのは分かったけど、`.env.production`が盗まれたら元も子もないのでは？」

その通りです。
そこで、`.env.production`をGitHubにアップしないようにセッティングします。

プロジェクトフォルダ直下に`.gitignore`ファイルを作成します。
このファイルに記載されたファイルは、gitにcommitされません。
`.gitignore`に次のように追記します。
```ruby:.gitignore
(略)
.env.production
```
試しにGitHubにpushしてみます。
![スクリーンショット 2022-09-25 10.09.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2688241/31409c4a-99d4-9f60-e3c4-ddd5d54dabb1.png)

確かに`.env.production`がpushされていないことが分かります。
もしここに`.gitignore`で指定したファイルがアップされていたら下記記事を参照にpushしなおしてみてください。

https://qiita.com/fuwamaki/items/3ed021163e50beab7154

（僕は`.gitignore`のファイル名が間違っていてpushされていたので、そのへんもチェックしてみてください。）


## データベースをつくる
やっと準備が終わりました。
データベースを作っていきましょう。
ターミナルにて
```
$ bundle exec rails db:create
```
を実行し、下記のようなメッセージが出ればPostgreSQLでデータベースの作成完了です。

```
Created database 'db/development.sqlite3'
Created database 'db/test.sqlite'
```

**え？　作成されたデータベース、SQlite3じゃん**
と思われるかもしれませんが、現在いるのは開発環境ですので、これでOKです。

実際に本番環境でデータベースを動かす方法は、次の記事で紹介します。

# まとめ

以上で、SQlite3から本番環境だけPostgreSQLに変更する方法を紹介しました。

下に紹介する様々な記事に感謝すると同時に、本記事が誰かの役に立つことを願っています。

# 参考記事

[Ruby on Railsの新しいプロジェクトでSQLite3からPostgreSQLに変更する](https://qiita.com/rubys8arks/items/0749d6fa73e88d3d381c)

[MacにPostgreSQLを導入する方法&初期設定をおこなう](http://vdeep.net/mac-postgresql)

[【Rails】環境変数（.env）を設定・取得する方法](https://labo.kon-ruri.co.jp/rails-dotenv/)

[Railsガイド#データベースを設定する](https://railsguides.jp/configuring.html#%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)