railsのフォロー機能コードベタ貼りメモ

かなり自分用。アウトプットしないと忘れそうなので記録。分かりやすくはない。

```rb:db/migrate/relationships.rb
  def change
    create_table :relationships do |t|
      t.integer :follower_id
      t.integer :followed_id

      t.timestamps
    end
```

```rb:model/relationships.rb
    belongs_to :follower, class_name: "User"
    belongs_to :followed, class_name: "User"
```

```rb:model/user.rb
  #userﾃｰﾌﾞﾙ→relationﾃｰﾌﾞﾙ
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  #relationﾃｰﾌﾞﾙ→followedﾃｰﾌﾞﾙ、followed_idを持って来る
  has_many :followings, through: :relationships, source: :followed
  
  #followerﾃｰﾌﾞﾙ(本当はuser)→re_relationﾃｰﾌﾞﾙ(本当relation)へfollowed_idを送る(参照）
  has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id", 
  dependent: :destroy
  #re_relationﾃｰﾌﾞﾙ→userﾃｰﾌﾞﾙへfollower_idを持って来る
  has_many :followers, through: :reverse_of_relationships, source: :follower
 
  def follow(user_id)
    relationships.create(followed_id: user_id)
  end

  def unfollow(user_id)
    relationships.find_by(followed_id: user_id).destroy
  end

  def following?(user)
    followings.include?(user)
  end
```

```rb:routes.rb
  resources :users, only: [:show,:index,:edit,:update] do
    resources :relationships, only: [:create, :destroy] do
      member do
        get 'following' => 'relationships#followings', as: 'followings'
        get 'followers' => 'relationships#followers', as: 'followers'
      end
    end
  end
#menberよりcollectionのほうがいかも
```

```rb:relationships_controller.rb
  def create
    current_user.follow(params[:user_id])
    redirect_to request.referer
  end
  def destroy
    current_user.unfollow(params[:user_id])
    redirect_to request.referer
  end
```

```erb:view/users/どこか

    <% users.each do |user| %>
      <tr>
        <td>
          フォロー数:<%= user.followings.count %>
        </td>
        <td>
          フォロワー数:<%= user.followers.count %>
        </td>
　　　   <td>
          <% unless user == current_user %>
            <% if current_user.following?(user) %>
              <%= link_to 'unfollow', user_relationship_path(user.id, current_user.id), method: :delete %>
            <% else %>
              <%= link_to 'follow', user_relationships_path(user.id), method: :post %>
            <% end %>
          <% end %>
        </td>
      </tr>
    <% end %>
  </tbody>

```

<h1>説明</h1>
1行目のrelationshipsはフォローした時にそのカラムを新規保存するときに使う。

```rb:
relationship = relationships.new(followed_id: user_id)
relationship.save
```
イメージはこんな感じ
2行目のfollowingsは```@user = User.find(params[:id])```で特定のuser_idを抽としたときに```@user.followings```で@userのフォロワー一覧が出せる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110799/09dae96a-08cb-4541-59d9-11da70865e5b.png">

１、２行目はusersテーブル→relationshipsテーブル→usersテーブルのフォローする人の一連の流れを表している
３、４行目はusersテーブル→relationshipsテーブル→usersテーブルのフォローされる人の一連の流れを表している

１行目はUserテーブルからrelationshipsテーブルに値を受け渡すための文。
例えばUser.find(1).relationshipsの記載だとUserid1なのでrelationshipsのfollower_idが1のrelationshipsのidが返される。

２行目がカラム→Viewにカラムを渡す時の文。
例えばUserのid1の人のフォロー『されてる』人を参照したいときはUser.followingsとやれば「follower_idが１」のfollowed_idを全部持ってきて！となり、User_id1の人のフォローされてる人をviewに持ってこれる

<h2>自分メモ</h2>
```followers, through: :reverse_of_relationships, source: :followed```は
followersからreverse_of_relationshipsを通ってfollowedを持って来るという意味。sourceは持って来る側だから定義しているものの逆を書くイメージ。私は逆で認識してた。あとuserに対してfollowingsとやると沢山のfollowed_idが現れること。多対多ということを忘れず！！