0
0

More than 1 year has passed since last update.

フォロー機能の追加方法(Ruby on Rails)

Posted at

今回の課題 "フォロー機能の追加"

Railsでのフォロー機能の追加について難しかった点などを
自分で記事に書いて、頭の中を整理していこうと思います。
間違いなどありましたら、ご教授の程よろしくお願い致します。

開発環境

ruby 2.6.3
Rails 5.2.6
Bootstrap 4.5
Cloud9

大事なこと

今回はフォローした人とフォローする人
どちらも同じテーブル内に存在するUserです。
多くの人をフォローすることもできるし、多くの人にフォローされることもある状態なので現在は多対多の関係になっています。なので
1対Nの関係を中間テーブルを用いて関連付ける事が重要になります。

自分自身もまだ完全には理解できていませんが、この記事を書く事で少しでも理解できる様に整理していきます。

手順

  • モデルの作成
  • アソシエーション
  • メソッド作成
  • コントローラー
  • ビュー

モデルの作成

まずはrelationshipモデルを作成

そしてrelationshipsテーブル内のカラムに
・integer :follower_id(フォローしたUser)
・integer :followed_id(フォローされたUser)
の2つのカラムを追加します。

$ rails g model Relationship follower_id:integer followed_id:integer
$ rails db:migrate

アソシエーション

関係性を整理すると
"1人のUserは多くの人をフォローできる"
"1人のUserは多くの人からフォローされる"
と考えると1対Nの関係性が出来上がります。

Relationshipモデル

models/relationship.rb
class Relationship < ApplicationRecord
  # belongs_to :userにするとフォローするuserなの?フォローされるuserなの?となる
  # このままだと存在しないテーブルを探しに行くので、class_name: で"User"を指定
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
end

Userモデル

models/user.rb
#foreign_keyには、@user.xxxとした際に「@user.idがfollower_idなのかfollowed_idなのか」を指定する
#フォローした人、された人の関係性を記述
has_many :relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy

# 一覧画面で使う用の記述
# そのユーザーがフォローしている人の一覧を表示させる為
has_many :followings, through: :relationships, source: :followed
# そのユーザーがフォローされている人の一覧を表示させる為
has_many :followers, through: :reverse_of_relationships, source: :follower

続いてモデルにメソッドを記述していきます。

models/user.rb
#フォローをした際の処理
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)
  following.include?(user)
end

こう記述することでコントーローラ内の記述を見やすくする。

Relationshipsコントローラーの作成と記述

$ rails g controller Relationships
controllers/relationships_contoller.rb
class RelationshipsController < ApplicationController

 #フォローするときの処理
  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
 #フォローの一覧画面
  def followings
   user = User.find(params[:user_id])
   @users = user.followings
  end
 #フォロワーの一覧画面
  def followers
   user = User.find(params[:user_id])
   @users = user.followers
  end
end

コントローラ作成後、ルーティングも設定します。

config/routes.rb
#ネストさせる

 resources :users do
  resource :relationships, only:[:create, :destroy]
  get "followings" => "relationships#followings", as: "followings" 
  get "followers" => "relationships#followers", as: "followers"
 end

ビューの記述をする

フォローボタンの設置

お好きなところ
 #もしログインユーザーがフォローしてる一覧内に、(user)が含まれていたら?
 <% if current_user.followings?(user)%>
  <%= link_to "フォロー外す", user_relationships_path(user.id), method: :delete %>
 <% else %>
  <%= link_to "フォローする", user_relationships_path(user.id), method: :post %>
 <% end %>

フォロー・フォロワー一覧画面

部分テンプレート
#もしユーザーが存在したら一覧表示(usersには@変数を入れる)
<% if users.exists? %>
  <% users.each do |user| %>
    <table>
      <thead>
        <tr>
          <th>name</th>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><%= user.name %></td>
          <td>フォロー数: <%= user.followings.count %></td>
          <td>フォロワー数: <%= user.followers.count %></td>
        </tr>
      </tbody>
    </table>
  <% end %>
#もしユーザーが存在しなければ
<% else %>
  <p>ユーザーはいません</p>
<% end %>

あとは部分テンプレートを、render で呼び出して各ビューに貼る

まとめ

最後の方は文章などが少なくなりましたが、記述の内容をちゃんと理解して
流れを理解できる様になればもっとわかる様になると思いました。

もっと日々勉強を続けて、スキルアップしていける様に努力します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0