LoginSignup
1
5

More than 3 years have passed since last update.

フォロー機能(Ajax)実装

Last updated at Posted at 2020-08-03

自分用にまとめます。

実装

モデル作成

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


マイグレーションファイル

20200723070930_create_relationships.rb
class CreateRelationships < ActiveRecord::Migration[5.2]
  def change
    create_table :relationships do |t|
      t.integer :follower_id, null: false
      t.integer :followed_id, null: false

      t.timestamps
    end
  end
end


relationship.rb
class Relationship < ApplicationRecord

  # フォローするユーザー
  belongs_to :follower, class_name: 'User'
  # フォローされるユーザー
  belongs_to :followed, class_name: 'User'

  validates :follower_id, presence: true
  validates :following_id, presence: true

end

class_name: 'User':「followerもfollowedもUserにいるよ」という意味


app/models/user.rb
class User < ApplicationRecord

  # フォロー取得
  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


  # ユーザーをフォローする
  def follow(user_id)
    follower.create(followed_id: user_id)
  end

  # ユーザーのフォローを外す
  def unfollow(user_id)
    follower.find_by(followed_id: user_id).destroy
  end

  # フォロー確認を行う
  def following?(user)
    following_user.include?(user)
  end

end


コントローラ作成

$ rails g controller relationships


config/routes.rb
Rails.application.routes.draw do

  post 'follow/:id', to: 'relationships#follow', as: 'follow'
  post 'unfollow/:id', to: 'relationships#unfollow', as: 'unfollow'
  get 'users/following/:user_id', to: 'users#following', as: 'users_following'
  get 'users/follower/:user_id', to: 'users#follower', as: 'users_follower'

end


users_controller.rb
class UsersController < ApplicationController

  # @userがフォローしているユーザー一覧
  def following
    @user = User.find(params[:user_id])
    @followings = @user.following_user
  end

  # @userをフォローしているユーザー一覧
  def follower
    @user = User.find(params[:user_id])
    @followers = @user.follower_user
  end

end


relationship_controller.rb
class RelationshipsController < ApplicationController

    # フォローする
    def follow
      @user = User.find(params[:id])
      current_user.follow(params[:id])
      render :create
    end

    # アンフォローする
    def unfollow
      @user = User.find(params[:id])
      current_user.unfollow(params[:id])
      render :destroy
    end

end

renderでcreate.js.erbとdestroy.js.erb呼び出すことで、
ページ遷移なしでフォロー・解除が行えるようになる。


users/show.html.slim
# create.js.erbとdestroy.js.erbで書き換えるため記述必須
div id="follow_form"

  # フォローボタン部分をパーシャルで飛ばす
  = render 'relationships/follow', user: @user 


_follow.html.slimファイルをrelationshipsディレクトリ配下に手動で作成
パーシャルで飛ばしたフォローボタン部分の記述を貼り付ける。

relationships/_follow.html.slim
- unless user == current_user
  - if current_user.following?(user)

    # jsファイルを呼び出すためにremote: trueを追記
    = link_to unfollow_path(user), method: :post, remote: true, class: 'btn btn-outline-info m-0 btn-sm' do
      i.fas.fa-user フォロー中
  - else

    # jsファイルを呼び出すためにremote: trueを追記
    = link_to follow_path(user), method: :post, remote: true, class: 'btn btn-outline-success m-0 btn-sm' do
      i.far.fa-user フォローする


create.js.erbファイルをrelationshipsディレクトリ配下に手動で作成

relationships/create.js.erb

# id="follow_form"部分を_follow.html.slimの内容にページ遷移なしで書き換える
$('#follow_form').html("<%= j(render 'relationships/follow',{ user: @user }) %>");


destroy.js.erbファイルをrelationshipsディレクトリ配下に手動で作成

relationships/destroy.js.erb

# id="follow_form"部分を_follow.html.slimの内容にページ遷移なしで書き換える
$('#follow_form').html("<%= j(render 'relationships/follow',{ user: @user }) %>");

完成!

1
5
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
1
5