MacのRailsアプリでPostgreSQLを使う方法

#はじめに
MacでPostgreSQLを用いたRailsアプリを開発する際の環境設定についてメモします。

#開発環境
- OS
    - Mac OS X
        - 10.10.5
- Software
    - PostgreSQL
        - 9.3.5
    - Ruby
        - 2.2.2
    - Rails
        - 4.2.2以降

#PostgreSQLのインストール
PostgreSQLのインストールにはHomebrewを使います。

```
$ brew install postgresql
```

無事にインストールされたか確認します。

```
$ postgres --version
postgres (PostgreSQL) 9.3.5
```

上記の様に出力されればOKです。

#PostgreSQLの設定

##データベースクラスタの作成

PostgreSQLにはデータベースクラスタという概念があります。データベースクラスタとはデータベースの集合のことで、PostgreSQLではデータベースクラスタを設定してその中にデータベースを作成することとなります。

PostgreSQLでデータベースクラスタを作るには、initdbコマンドを用います。

```
$ initdb /usr/local/var/postgres -E utf8
The files belonging to this database system will be owned by user "mac_user".
This user must also own the server process.

The database cluster will be initialized with locale "ja_JP.UTF-8".
initdb: could not find suitable text search configuration for locale "ja_JP.UTF-8"
The default text search configuration will be set to "simple".

Data page checksums are disabled.

creating directory /usr/local/var/postgres ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
creating configuration files ... ok
creating template1 database in /usr/local/var/postgres/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating collations ... ok
creating conversions ... ok
creating dictionaries ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
loading PL/pgSQL server-side language ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok
syncing data to disk ... ok

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    postgres -D /usr/local/var/postgres
or
    pg_ctl -D /usr/local/var/postgres -l logfile start
```

ここでは、文字コードをUTF-8に初期化していますが、若干コケています。ただし、運用上は問題なさそうなので、無視して進みます。

また、ここでinitdbコマンドの引数に指定したディレクトリ名を変更することで、異なる場所にデータベースクラスタを構成することができます。この要領で複数のデータベースクラスタを作ることも可能です。

次に、データベースクラスタが作成されたか確認するため、PostgreSQLを起動します。

```
$ postgres -D /usr/local/var/postgres
LOG:  database system was shut down at 2015-11-01 23:00:02 JST
LOG:  database system is ready to accept connections
LOG:  autovacuum launcher started
```

上のようなログが書き出されればOKです。

上記のコマンドを走らせたまま、別ウィンドウでデータベースクラスタ内のデータベースを確認してみます。後で、PostgreSQLを自動起動させる設定を行います。

```
$ psql -l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | mac_user | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 |
 template0 | mac_user | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/mac_user          +
           |          |          |             |             | mac_user=CTc/mac_user
 template1 | mac_user | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/mac_user          +
           |          |          |             |             | mac_user=CTc/mac_user
(3 rows)
```

デフォルトで、3つのデータベースが作られていることが確認できます。

次に、~/.bash_profileに以下を追記します。

```
export PGDATA=/usr/local/var/postgres
```

これで、PostgreSQLがデフォルトで参照するデータベースクラスタが定まりました。

###バックグラウンドでPostgreSQLを起動する方法

- PGDATAが設定してある場合
    - 起動
        - $ pg_ctl -l /usr/local/var/postgres/server.log start
    - 終了
        - $ pg_ctl stop
- PGDATAが設定されていない場合（PGDATAのパス以外のDBを起動させる場合）
    - 起動
        - $ pg_ctl -D \<initdbで指定したディレクトリ\> -l /usr/local/var/postgres/server.log start
    - 終了
        - 同上

また、注意点として、「-l」でログの出力先を渡さないと、ログが標準出力されて気持ち悪いことになります。

ここまでで、PostgreSQLを起動させるための設定が終わりました。

##ユーザ（ロール）の作成

PostgreSQLでは、データベースの作成時にオーナーとなるユーザを指定する必要があるため、データベース作成前にユーザを作成する必要があります。後からオーナーを変更する場合は、後でユーザ作成する選択肢もあります。

デフォルトでは、以下のようになっています。

```
$ psql -q -c'select * from pg_user' postgres
 usename  | usesysid | usecreatedb | usesuper | usecatupd | userepl |  passwd  | valuntil | useconfig
----------+----------+-------------+----------+-----------+---------+----------+----------+-----------
 mac_user |       10 | t           | t        | t         | t       | ******** |          |
(1 row)
```

上記コマンドの最後の引数「postgres」はデータベース名で、これを指定しないとユーザと同一のデータベースを指定したことになり、以下の様にエラーが出力されます。

```
$ psql -q -c'select * from pg_user'
psql: FATAL:  database "mac_user" does not exist
```

次に、ユーザの作成には、createuserコマンドを用います。

```
$ createuser rails_user
$ psql -q -c'select * from pg_user' postgres
 usename    | usesysid | usecreatedb | usesuper | usecatupd | userepl |  passwd  | valuntil | useconfig
------------+----------+-------------+----------+-----------+---------+----------+----------+-----------
 mac_user   |       10 | t           | t        | t         | t       | ******** |          |
 rails_user |    16384 | f           | f        | f         | f       | ******** |          |
(2 rows)
```

rails_userが追加されていることがわかります。ここで、パスワードを設定したい場合には、createuserコマンドに-Pオプションを付加してください。

##データベースの作成

データベースの作成には、createdbコマンドを用います。

ここでは、rails_userがオーナーとなっているrails_devというデータベースを作成します。

```
$ createdb rails_dev -O rails_user
$ psql -l
                                      List of databases
   Name    |  Owner     | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+------------+----------+-------------+-------------+-----------------------
 postgres  | mac_user   | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 |
 template0 | mac_user   | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/mac_user          +
           |            |          |             |             | mac_user=CTc/mac_user
 template1 | mac_user   | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/mac_user          +
           |            |          |             |             | mac_user=CTc/mac_user
 rails_dev | rails_user | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 |
(4 rows)
```

以上で、データベースを作成することができました。

##データベースの権限設定

ここで、rails_devの権限を確認すると、

```
$ psql -q -c'select * from pg_user' rails_dev
 usename    | usesysid | usecreatedb | usesuper | usecatupd | userepl |  passwd  | valuntil | useconfig
------------+----------+-------------+----------+-----------+---------+----------+----------+-----------
 mac_user   |       10 | t           | t        | t         | t       | ******** |          |
 rails_user |    16384 | f           | f        | f         | f       | ******** |          |
(2 rows)
```

となっており、rails_userはオーナーではあるがすべての権限を持っていません。

また、データベースの権限は、PostgreSQLに入って確認することもできます。

```
$ psql -U rails_user rails_dev
psql (9.3.5)
Type "help" for help.

rails_dev=> \du
                             List of roles
 Role name  |                   Attributes                   | Member of
------------+------------------------------------------------+-----------
 rails_user |                                                | {}
 mac_user   | Superuser, Create role, Create DB, Replication | {}
```

では、rails_userのrails_devに対する権限を変更してみます。権限の変更はSuperuser権限を持っているmac_userで行います。

```
$ psql -U mac_user rails_dev
psql (9.3.5)
Type "help" for help.

rails_dev=# \du
                             List of roles
 Role name  |                   Attributes                   | Member of
------------+------------------------------------------------+-----------
 rails_user |                                                | {}
 mac_user   | Superuser, Create role, Create DB, Replication | {}

rails_dev=# ALTER ROLE rails_user WITH Superuser;
ALTER ROLE
rails_dev=# \du
                             List of roles
 Role name  |                   Attributes                   | Member of
------------+------------------------------------------------+-----------
 rails_user | Superuser                                      | {}
 mac_user   | Superuser, Create role, Create DB, Replication | {}
```

以上で、rails_userにスーパーユーザ権限を与えることができました。

#Railsの設定
まず、Rubyの環境を整えます。ここでは、rbenvを用いることを前提としています。

```
$ mkdir rails_app
$ cd rails_app
$ cat 2.2.2 > .ruby-version
$ gem install bundler
$ bundle init
```

次に、Railsのバージョンを設定します。今回は、4.2.2より新しいバージョンという指定をします。つまり、GemfileのRailsの設定箇所を以下の様に書き換えます。

```
gem "rails", "~>4.2.2"
```

最後に、gemパッケージをインストールし、Railsアプリを作成します。

```
$ cat Gemfile
# A sample Gemfile
source "https://rubygems.org"

gem "rails", "~>4.2.2"
$ bundle install --path vendor/bundle
...
$ bundle exec rails new . -T -d postgresql
       exist  
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
    conflict  Gemfile
Overwrite /Users/yhayashi/work/circle_around/sample/Gemfile? (enter "h" for help) [Ynaqdh] Y
...
```

これでRailsアプリは作成できましたが、先ほど設定したPostgreSQLの情報が反映されていません。そこで、config/database.ymlを変更し、データベースに接続するための設定を行います。今回は、開発環境（development）のみ設定します。

```
development:
  adapter: postgresql
  encoding: unicode
  database: rails_dev
  pool: 5
  username: rails_user
  password: ********（パスワードが無い場合には空白）
  host: localhost
```

以上で設定完了です。Railsサーバを立ち上げて、アプリの起動を確認しましょう！

```
$ bundle exec rails s
```