【Ruby on Rails】 팔로우 기능 구현 : 양방향

목표





개발 환경



루비 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

전제



※ ▶◯◯를 선택하면 설명 등이 나오므로,
잘 모르는 경우의 참고로 해 주시면 좋겠습니다.
  • devise로 로그인 환경 구축

  • 단방향 북마크(즐겨찾기 등록, 좋아요) 기능은 이쪽

    흐름



    1 모델 만들기
    2 모델을 수정 <-- 여기가 가장 어렵습니다.
    3 controller 만들기
    4 라우팅 수정
    5 view 만들기

    모델 만들기



    이번에는 Relationship 모델 만들기

    터미널
    $ rails g model Relationship follower_id:integer followed_id:integer
    

    터미널
    $ rails db:migrate
    

    보충
    follower_id와 followed_id는 가상의 id이며, 나중에 user 모델의 수정으로 기술해, 사용합니다.

    모델 수정



    app/models/relationship.rb
      belongs_to :follower, class_name: "User"
      belongs_to :followed, class_name: "User"
    

    보충
    메소드 이름을 변경하고 @relationship.follower와 같은 형태로 @relationship 에 붙은 user 레코드를 취득.
    ※메소드명 변경은, 팔로우와 팔로워를 나누기 위해서입니다.

    app/models/user.rb
      has_many :follower, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy # フォロー取得
      has_many :followed, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy # フォロワー取得
      has_many :following_user, through: :follower, source: :followed # 自分がフォローしている人
      has_many :follower_user, through: :followed, source: :follower # 自分をフォローしている人
    
      # ユーザーをフォローする、後ほどcontrollerで使用します。
      def follow(user_id)
        follower.create(followed_id: user_id)
      end
    
      # ユーザーのフォローを外す、後ほどcontrollerで使用します。
      def unfollow(user_id)
        follower.find_by(followed_id: user_id).destroy
      end
    
      # フォローしていればtrueを返す、後ほどviewで使用します。
      def following?(user)
        following_user.include?(user)
      end
    

    보충 1【1, 2행째에 대해서】

    우선, user는 많은 follower를 가지고,

    @user 에 끈 @relationship 레코드를 취득 가능하게 해,

    relaitonships 테이블에 액세스 할 때 follow_id를 입구로하고,

    user가 없어지면 삭제한다

    보충 2【3, 4행째에 대해서】

      우선, user는 많은 following_user를 가지고,

    follower를 통해 following_user를 취득 가능하게 해,

    user.following_user로 취득 가능하게 한다.

    보충 3【(followed_id: user_id)에 대해서】
    (followed_id: user_id)
    followed_id 에 user_id 를 대입한다
    라는 바람에 이미지하면 알기 쉽습니다.
    그리고는 문자 그대로의 의미입니다.

    controller 만들기



    터미널
    $ rails g controller relationships
    

    app/controllers/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
    

    이번에는 app/views/homes/mypage.html.erb에
    팔로우, 팔로워의 일람을 표시하기 위해서 아래의 장소에 기술.

    app/controllers/homes.controller.rb
      def mypage
        @following_users = current_user.following_user
        @follower_users = current_user.follower_user
      end
    

    라우팅 수정



    config.routes.rb
    resources :users do
      resource :relationships, only: [:create, :destroy]
    end
    

    view에 추가 (인스턴스 변수가있는 경우)



    app/views/show.html.erb
    <% if current_user != user %>
      <% if current_user.following?(@user) %>
        <%= link_to 'フォロー外す', user_relationships_path(@user.id), method: :delete %>
      <% else %>
        <%= link_to 'フォローする', user_relationships_path(@user.id), method: :POST %>
      <% end %>
    <% end %>
    

    app/views/homes/mypage.html.erb
    <div>
      フォロー数: <%= current_user.follower.count %>
      フォロワー数:<%= current_user.followed.count %>
    </div><br><br>
    <table>
        <caption>フォロー中</caption>
        <thead>
            <tr>
                <th>ユーザー名</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <% @following_users.each do |following_user| %>
            <tr>
                <td><%= following_user.name %></td>
                <td><%= link_to 'フォロー外す', user_relationships_path(following_user.id), method: :delete %></td>
            </tr>
            <% end %>
        </tbody>
    </table><br><br>
    
    <table>
        <caption>フォロワー</caption>
        <thead>
            <tr>
                <th>フォロワー名</th>
            </tr>
        </thead>
        <tbody>
            <% @follower_users.each do |follower_user| %>
            <tr>
                <td><%= follower_user.name %></td>
            </tr>
            <% end %>
        </tbody>
    </table>
    

    참고


  • Rails에서 팔로우 기능을 만드는 방법
  • 협회에서 class_name의 정의!
  • 【Rails】다 대다의 어소시에이션에 별명을 붙이고 싶은 당신에게
  • 좋은 웹페이지 즐겨찾기