foreign_keyを設定しているカラムのカラム名を変更したときにはまったこと。

### 困っていたこと
先日、foreign_keyを設定していたカラムのカラム名を変更したときに、エラーにはまってしまったので、備忘も兼ね記事に残しておこうと思います。

なお、実行環境は下記のとおりです。

- Rails 5.2.4.2
- PostgreSQL 12.2

### 前提条件
従業員の活動を記録するデータベースにおいて、従業員(employees) は 活動(activities)と多対多の関係にあります。下記のようなUIで一気に活動に参加した従業員を記録したく、

![ui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393888/73a08f43-114b-a43c-8d99-c03bd1a6a1a4.png)

以下のコードを書きました。

### 作成したコード
**Model**
activitiesとemployeesで多対多の関係を定義し、中間テーブルを`activity_employees`としています。

```Ruby:models/employee.rb
class Employee < ApplicationRecord
  has_many :activity_employees, dependent: :destroy
  has_many :activities, through: :activity_employees
end
```
```ruby:models/activity.rb
class Activity < ApplicationRecord
  has_many :activity_employees, dependent: :destroy
  has_many :employees, through: :activity_employees
end
```
```ruby
class ActivityEmployee < ApplicationRecord
  belongs_to :activity
  belongs_to :employee
end
```

**Controller**
一気にデータを受け取れるよう、`employee_ids: []`をstrong paramaterに入れています。

```ruby
class ActivitiesController < ApplicationController
  # 略
  def create
    @activity = @facility.activities.build(activity_params)
    if @activity.save
      # 処理
    else
      # 処理
    end
  end

  private
  def activity_params
    params.require(:activity).permit(
      :activity_type,
      # 略,
      employee_ids: [],
      # 略
      )
  end
end
```

**View**

```ruby
= form_with model: [@facility, @activity], class: "p-input-form", local: true do |f|

  = f.collection_check_boxes :employee_ids, @employees, :id, :name, include_hidden: false do |t|
    = t.label(class: "c-check-box__label mr-4") { t.check_box(class: "c-check-box") + t.text }
```

### 起こっていた問題
上記のコードでデータを保存しようとすると、下記のエラーが出ていました。
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393888/84491cd0-48d1-2a95-c5f4-c99a1079118a.png)
え。。。。`staffs`テーブルにデータを保存しようとなんでしていない。。。。なぜ、`staffs`テーブルの参照整合性を崩すというエラーになるの？？？

### 調べたこと
1. `activity_params`として送っているデータの中身を調べました。
→ こちらに間違いはなかったので、略

2. `db:schema:dump`をして`schema`ファイルを最新化したのち、値を調べました。

```ruby:db/schema.rb
create_table "activity_employees", force: :cascade do |t|
  t.bigint "activity_id"
  t.bigint "employee_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["activity_id"], name: "index_activity_employees_on_activity_id"
  t.index ["employee_id"], name: "index_activity_employees_on_employee_id"
end
```
…カラム名は正しい。。。おかしくなさそう。。。。

いったい何が。。。？と思っていたら、`annotate`というgemによってモデルに自動生成されている記述の中に、見つけました！

```rails:models/activity_employee.rb
# Foreign Keys
#
#  fk_rails_...  (activity_id => staffs.id)
#  fk_rails_...  (employee_id => employees.id)
```
**カラム名が`activity_id`なのに、参照先が`staffs`テーブルだ！！**:eyes:

### 問題の原因
原因を探るためmigrationファイルをたどっていくと。。。。
▼こちらのマイグレーションの後に、

```ruby:migration1
class CreateActivityEmployees < ActiveRecord::Migration[5.2]
  def change
    create_table :activity_employees do |t|
    t.references :staff, foreign_key: true
    t.references :facility_employee, foreign_key: true
    t.timestamps
  end
end
```
カラム名間違えたわ！！！…と
▼こんなマイグレーションを作っていました

```ruby:migration2
class RenameStaffIdColumnToActivityEmployees < ActiveRecord::Migration[5.2]
  def change
    rename_column :activity_employees, :staff_id, :activity_id
  end
end
```

その結果、カラム名は変更できたのですが、`foreign_key`は変更できていなかったようです。
### 解決策
上記を踏まえて、以下のようなマイグレーションを作成し、実行することで解決しました。

```ruby:migration3
class ChangeReferencesOfActivityEmployeesTable < ActiveRecord::Migration[5.2]
  def change
    remove_foreign_key :activity_employees, :staffs
    add_foreign_key :activity_employees, :activities
  end
end
```

postgresにまだ慣れていなかったので、gemの`annotate`を入れてDBの中身が見えるようにしておかないと、気づけないエラーでした。`*_id`というカラムでは、カラム名を変更しても`foreign_key`を変更したことにはならないのね＾＾；

マイグレーションファイルを作るときのカラム名には、今後はより一層の注意を払おうと思います:cry: