Active Recordを単体で使ってRailsで複数DB接続する

## はじめに
Rails6では、標準で複数DB接続がサポートされるようですね。。。早く使いたい。。。
Rails5のプロジェクトで、別DBから情報を引っ張ってきたいという要件があったので、試してみました。

## ポイント
複数DBを扱うに当たって、めんどくさいことはマイグレーションでしょう。
今回は、別サービスから別サービスのDBへ単純に参照したいという要件なので、シンプルに行きます。
マイグレーション自体も、頑張れば複数DB用に管理できますが、結構めんどくさいです。
あと、Railsに慣れていると勘違いしてしまうかもしれませんが、Active Record自体はマイグレーションは必要ありません。
接続情報さえあれば、基本的にはいつも通り使えます。

## データベース
今回は、こんな感じのテーブルがある感じです。

```
mysql> desc users;
+-------------------+---------------------+------+-----+---------+----------------+
| Field             | Type                | Null | Key | Default | Extra          |
+-------------------+---------------------+------+-----+---------+----------------+
| id                | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| name              | varchar(255)        | NO   |     | NULL    |                |
| email             | varchar(255)        | NO   | UNI | NULL    |                |
| email_verified_at | timestamp           | YES  |     | NULL    |                |
| password          | varchar(255)        | NO   |     | NULL    |                |
| remember_token    | varchar(100)        | YES  |     | NULL    |                |
| created_at        | timestamp           | YES  |     | NULL    |                |
| updated_at        | timestamp           | YES  |     | NULL    |                |
+-------------------+---------------------+------+-----+---------+----------------+
```

## Gemを入れる
今回は、実験的にシンプルなRubyプロジェクトからDBをActive Recordを使って参照してみます。
あと、適当にMysql2を入れときます。テスト用に立てたMariaDBに繋いでみたんですが、普通に繋がりますね。

```ruby:Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'activerecord'
gem 'mysql2'
```

## 別DB接続用のクラスを作る

それでは、やっていきます。
ActiveRecord::Base#establish_connectionに接続情報を渡してやれば、使えるわけですが
ベストプラクティスとしては、やはり別DB接続用の抽象クラスを作っておくことでしょうか。


```ruby:connector.rb
require 'bundler/setup'
require 'active_record'

class Connector < ActiveRecord::Base
  self.abstract_class = true
  con = {
    adapter: 'mysql2',
    host:    'your_db_host',
    username: 'root',
    password: 'password',
    database: 'test_db'
  }
  establish_connection(con)
end
```

したら、こいつを継承した具象クラスを作ります。
これに関しては、ActiveRecordの命名規則に従うなり、オプションでテーブル名を指定するなりしてやってください。

```ruby:user.rb
require './connector.rb'

class User < Connector
  scope :id, -> (id) { where(id: id) if id.present? }
end
```

## 動作確認
irbで動作確認してみます。

```shell

> irb
irb(main):001:0> require './user.rb'
=> true
irb(main):002:0> User.count
=> 2
irb(main):003:0> User.first
=> #<User id: 1, name: "test", email: "test@test.org", email_verified_at: nil, password: "password", remember_token: nil, created_at: "2019-06-17 00:00:00", updated_at: nil>
irb(main):004:0> user = User.new(id: 3, name: 'from active record', email: 'active_record@test.org', password: 'password')
=> #<User id: 3, name: "from active record", email: "active_record@test.org", email_verified_at: nil, password: "password", remember_token: nil, created_at: nil, updated_at: nil>
irb(main):005:0> user.save!
=> true
irb(main):006:0> User.count
=> 3
irb(main):007:0> User.id(1)
=> #<ActiveRecord::Relation [#<User id: 1, name: "test", email: "test@test.org", email_verified_at: nil, password: "password", remember_token: nil, created_at: "2019-06-17 00:00:00", updated_at: nil>]>
irb(main):008:0> User.find(1).email
=> "test@test.org"
```

いいですね、普通に動きました。
普通にActive Recordとしても使えますし、コネクションだけ用意して生SQL叩くとかの使い方も考えられますね。

### 参考
[ActiveRecordを単体で使うには](https://tsuchikazu.net/active_record_single_use/)
[複数のDBにまたがるRailsの運用方法まとめ](https://qiita.com/KentFujii/items/8989e3d0730d4682545c)
[ActiveRecordで生SQLを使いたいときに便利なメソッド達](https://qiita.com/yut_h1979/items/4cb3d9a3b3fc87ca0435)