1つのモデルに別の1つのモデルを複数個持たせる方法[Rails5]

# 1つのモデルに別の1つのモデルを複数個持たせる方法

rails5にて[[Rails] 同じmodelを参照する外部キーを一つのmodelでもつ方法](https://qiita.com/takeoverjp/items/bb56d6a8eae191cd3732)と  
同様のことを実施したらdbへの登録時に  

```console
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: main.receivers:
```

エラーが出てハマったので備忘録

## 環境

ruby 2.3.5
rails 5.2.3

## やりたいこと

1. MemberモデルとMoneyRecordモデルがある
2. MoneyRecordモデルに送り主(Sender)と受取人(Receiver)を持たせる
3. SenderとReceiverはMemberモデルと紐づける

dbは以下の通り

members

| カラム名    | 型              |
| ----------- | --------------- |
| id          | integer/primary |
| member_name | string          |
| created_at  | timestamp       |
| updated_at  | timestamp       |

money_records

| カラム名    | 型              |
| ----------- | --------------- |
| id          | integer/primary |
| sender_id   | FK              |
| receiver_id | FK              |
| created_at  | timestamp       |
| updated_at  | timestamp       |

## 解決法

### マイグレーションファイル

マイグレーションファイルに `to_table` オプションをつけることで  
参照先テーブル名を明示的に指定してあげればできます。  
参照：[マイグレーションにおいて参照先テーブル名を自動で推定できないカラムを外部キーとして指定する方法](https://qiita.com/kymmt90/items/03cb9366ff87db69f539)

money_recordsのsenderとreceiverの `foreign_key: true` を以下に書き換え

```create_money_records.rb
class CreateMoneyRecords < ActiveRecord::Migration[5.2]
  def change
    create_table :money_records do |t|
      t.references :sender, foreign_key: { to_table: :members }
      t.references :receiver, foreign_key: { to_table: :members }

      t.timestamps
    end
  end
end
```

※membersのマイグレーションはデフォルトでOK

```create_member.rb
class CrceateMembers < ActiveRecord::Migration[5.2]
  def change
    create_table :members do |t|
      t.string :member_name

      t.timestamps
    end
  end
end
```

### モデル

Memberモデルからはクラス名と外部キーを、MoneyRecordモデルからはクラス名を指定してあげる。

```member.rb
class Member < ApplicationRecord
  has_many :sender_records,   class_name: 'MoneyRecord', foreign_key: 'sender_id'
  has_many :receiver_records, class_name: 'MoneyRecord', foreign_key: 'receiver_id'
end
```

```money_record.rb
class MoneyRecord < ApplicationRecord
  belongs_to :sender,   class_name: 'Member'
  belongs_to :receiver, class_name: 'Member'
end
```

## 結果

#### 登録

```console
pry(main)> member_1 = Member.new(member_name: "hoge")
=> #<Member:0x00007f0db4c23e68 id: nil, member_name: "hoge", created_at: nil, updated_at: nil>

pry(main)> member_1.save
   (0.1ms)  begin transaction
  Member Create (3.1ms)  INSERT INTO "members" ("member_name", "created_at", "updated_at") VALUES (?, ?, ?)  [["member_name", "hoge"], ["created_at", "2019-09-26 03:08:49.593452"], ["updated_at", "2019-09-26 03:08:49.593452"]]
   (3.6ms)  commit transaction
=> true

pry(main)> member_2 = Member.new(member_name: "fuga")
=> #<Member:0x00007f0db4b0d420 id: nil, member_name: "fuga", created_at: nil, updated_at: nil>

pry(main)> member_2.save
   (0.1ms)  begin transaction
  Member Create (5.2ms)  INSERT INTO "members" ("member_name", "created_at", "updated_at") VALUES (?, ?, ?)  [["member_name", "fuga"], ["created_at", "2019-09-26 03:09:47.400686"], ["updated_at", "2019-09-26 03:09:47.400686"]]
   (4.0ms)  commit transaction
=> true

[6] pry(main)> mr = MoneyRecord.new(sender: member_1, receiver: member_2)
=> #<MoneyRecord:0x00007f0db497ed48 id: nil, sender_id: 1, receiver_id: 2, created_at: nil, updated_at: nil>

[7] pry(main)> mr.save
   (0.1ms)  begin transaction
  MoneyRecord Create (2.2ms)  INSERT INTO "money_records" ("sender_id", "receiver_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["sender_id", 1], ["receiver_id", 2], ["created_at", "2019-09-26 03:10:10.874060"], ["updated_at", "2019-09-26 03:10:10.874060"]]
   (4.0ms)  commit transaction
=> true

# 無事登録できた！
```

#### 参照

```console
# MoneyRecord -> Member の参照
pry(main)> mr.sender
=> #<Member:0x00007f0db4c23e68 id: 1, member_name: "hoge", created_at: Thu, 26 Sep 2019 03:08:49 UTC +00:00, updated_at: Thu, 26 Sep 2019 03:08:49 UTC +00:00>

pry(main)> mr.receiver
=> #<Member:0x00007f0db4b0d420 id: 2, member_name: "fuga", created_at: Thu, 26 Sep 2019 03:09:47 UTC +00:00, updated_at: Thu, 26 Sep 2019 03:09:47 UTC +00:00>

# 参照できてた！

# Member -> MoneyRecord の参照
pry(main)> member_1.sender_records[0]
=> #<MoneyRecord:0x00007f0db4625fc0 id: 1, sender_id: 1, receiver_id: 2, created_at: Thu, 26 Sep 2019 03:10:10 UTC +00:00, updated_at: Thu, 26 Sep 2019 03:10:10 UTC +00:00>

pry(main)> member_2.receiver_records[0]
=> #<MoneyRecord:0x00007f0db459c1f8 id: 1, sender_id: 1, receiver_id: 2, created_at: Thu, 26 Sep 2019 03:10:10 UTC +00:00, updated_at: Thu, 26 Sep 2019 03:10:10 UTC +00:00>

# 参照できてた！
```