Railsチュートリアル第14章でアホみたいにハマった独学者の備忘録

Railsチュートリアル第１４章の　１４．１．５　フォロワーの演題で盛大にハマったので備忘録を残します。

#14章でどんなことを勉強するのか
Railsチュートリアルでは、Twitteサービスのクローンを作っています。
第14章では、Twtterでいうところのfollowとfollowerの機能を実装しながら勉強します。

#どんなところではまったのか
フォローするユーザーとフォローされるユーザーを記録するために、
この章で扱うデータモデルの構成は、以下に示すような関係になっていました。

Userテーブル

|   id   | name | email |
|:-----:|:-----:|:-----:|
| 1 | foo | bar@bar.com |

↓ userテーブルのidとfollower_idをthroughで紐づけ

|   follower_id     |       followed_id |
|:-----------------:|:------------------:|
|     :kissing_closed_eyes: 1         |            **2** → |
|      :kissing_closed_eyes: 1         |            **3** →|
|      3         |              2 |               
|      5         |              2 |
|     :kissing_closed_eyes: 1         |            **6** →|
|      2         |              2 |

↓ followed_idでuser.followingという配列を作成する
 :has_many

| id | name | email |
|:--:|:----:|:-----:|
|→2   | ... | ... |

| id | name | email |
|:--:|:----:|:-----:|
|→3   | ... | ... |

| id | name | email |
|:--:|:----:|:-----:|
|→6   | ... | ... |


##コードで表すと
```ruby:app/models/user.rb
  has_many :active_relationships,  class_name:  "Relationship",
                                   foreign_key: "follower_id",
                                   dependent:   :destroy
  has_many :passive_relationships, class_name:  "Relationship",
                                   foreign_key: "followed_id",
                                   dependent:   :destroy
  has_many :following, through: :active_relationships,  source: :followed
  has_many :followers, through: :passive_relationships, source: :follower
```

上記の記述により、様々なメソッドが使えるようになります。

| active_relationship.follower | フォロワーを返します |
|:--|:--|
| active_relationship.followed | フォローしているユーザーを返します |
| user.active_relationships.create(followed_id: other_user.id) | userと紐付けて能動的関係を作成/登録する |
| user.active_relationships.create!(followed_id: other_user.id) | userを紐付けて能動的関係を作成/登録する (失敗時にエラーを出力) |
| user.active_relationships.build(followed_id: other_user.id) | userと紐付けた新しいRelationshipオブジェクトを返す |

Railsが作ってくれたメソッドに加えて、チュートリアルでは以下のようなメソッドも定義しました。

```ruby:app/models/user.rb
class User < ApplicationRecord
  .
  .
  .
  def feed
    .
    .
    .
  end

  # ユーザーをフォローする
  def follow(other_user)
    following << other_user
  end

  # ユーザーをフォロー解除する
  def unfollow(other_user)
    active_relationships.find_by(followed_id: other_user.id).destroy
  end

  # 現在のユーザーがフォローしてたらtrueを返す
  def following?(other_user)
    following.include?(other_user)
  end

  private
  .
  .
  .
end
```

#演習課題は?
やっとここまでこれました。以下問題文。

**コンソールを開き、何人かのユーザーが最初のユーザーをフォローしている状況を作ってみてください。最初のユーザーをuserとすると、user.followers.map(&:id)の値はどのようになっているでしょうか?**

1.コンソール開いて、適当な変数名(user1, user2, user3)にUserテーブルの適当な値(User.firstとか)を代入
2.user2.follow(user1)でもいいし、railsがつくった user1.active_relationships.create(user2)でもいいからフォローとフォロワーを作成
3.user1.followers.map(&:id)でfollowerになったuserのidを配列で出力

できない...。

** 原因 **
follower_idとRelationテーブルのヒモ付を間違えてた。
正しいコードは

```ruby:app/models/user.rb
  has_many :passive_relationships, class_name:  "Relationship",
                                   foreign_key: "followed_id",
                                   dependent:   :destroy

  has_many :followers, through: :passive_relationships, source: :follower
```
間違えたコード has_many の through:　にactive_relationships渡してる...

```ruby:app/models/user.rb
  has_many :passive_relationships, class_name:  "Relationship",
                                   foreign_key: "followed_id",
                                   dependent:   :destroy

  has_many :followers, through: :active_relationships, source: :follower
```

解決まで時間かかりました。コードのミスって治すのが本当に難しいですね...
followメソッドが悪いのかな？user.active_relationships.createならいけるかも！とか
コンソールで試行錯誤したらこんな落ちでしたとさ！
Railsチュートリアル同じようにつまった人いたらこれが参考になりますように！