113
123

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

railsでフォロー機能をつける。

Last updated at Posted at 2017-04-17

メモ

環境
rails 5.0.0
ログイン機能は、deviseで作っている。

###フォロー機能つける前の状態

        deviseで、userモデルを作っている。パスワード以下の項目は省略

id 名前  メールアドレス
山田 yamada@yahoo.co.jp
佐藤 satouu@gmail.com
山本 yamamoto@yahoo.co.jp

 

本の登録するために、bookモデルを作っている。 内容は、本のタイトルと感想です。

| bookモデル | |
|:-----------------|------------------:|:------------------:
| id | 本のid |
| title | 本のタイトル |
| content | 本の感想  
| user_id | ユーザーid |

ターミナルで以下をします。
$rails generate model Relationship follower_id:integer following_id:integer

indexを追加、follower_idとfollowing_idをセットで一意にする。

ruby.20170416132621_create_relationships.rb

class CreateRelationships < ActiveRecord::Migration[5.0]
  def change
    create_table :relationships do |t|
      t.integer :follower_id
      t.integer :following_id

      t.timestamps null: false
    end

    add_index :relationships, :follower_id
    add_index :relationships, :following_id
    add_index :relationships, [:follower_id, :following_id], unique: true
  end
end

マイグレーションをする。

 $rake db:migrate

###フォローできるユーザーを取り出すに記述する。(user.following_relationships.followingsをできるようにする)

app/models/user.rb
has_many :following_relationships, foreign_key: "follower_id", class_name: "Relationship", dependent: :destroy

relationships.followingをできるようにする。

app/models/relationship.rb
 belongs_to :following, class_name: "User"
 validates :following_id, presence: true

1対多の関係になる。

###フォローしているユーザーを取り出す (user.followingsをできるようにする)

app/models/user.rb
has_many :following_relationships, foreign_key: "follower_id", class_name: "Relationship", dependent: :destroy

has_many :followings, through: :following_relationships
app/models/relationship.rb
    belongs_to :follower, class_name: "User"
    belongs_to :following, class_name: "User"
    validates :follower_id, presence: true
    validates :following_id, presence: true

###user.rbにフォローする関数、フォローしているか調べるための関数、フォローを外す関数を作成する

app/models/user.rb
 has_many :following_relationships, foreign_key: "follower_id", class_name: "Relationship", dependent: :destroy

 has_many :followings, through: :following_relationships

  def following?(other_user)
    following_relationships.find_by(following_id: other_user.id)
  end

  def follow!(other_user)
    following_relationships.create!(following_id: other_user.id)
  end

  def unfollow!(other_user)
    following_relationships.find_by(following_id: other_user.id).destroy
  end

###フォローされているユーザーを取り出す(user.follwersをできるようにする)

app/models/user.rb
 has_many :following_relationships, foreign_key: "follower_id", class_name: "Relationship", dependent: :destroy

 has_many :followings, through: :following_relationships

 has_many :follower_relationships, foreign_key: "following_id", class_name: "Relationship", dependent: :destroy

 has_many :followers, through: :follower_relationships

  def following?(other_user)
    following_relationships.find_by(following_id: other_user.id)
  end

  def follow!(other_user)
    following_relationships.create!(following_id: other_user.id)
  end

  def unfollow!(other_user)
    following_relationships.find_by(following_id: other_user.id).destroy
  end

###フォロー機能のルーティング

config/routes
 resources :users do
    member do
     get :following, :followers
    end
  end
  resources :relationships,       only: [:create, :destroy]

###users/showに、追加
フォローするために、各ユーザーに二つの機能をつける。一つ目は、フォローしている人数とフォローされている人数を示す表示。その数字を押すと、フォローしている/フォローされている人の一覧が出てくる。

二つ目は、このユーザーをフォローする/フォロー解除のボタンである。

s_screenshot 3.png

写真の説明
 一人目のユーザーでログインしている。一つ目のユーザーが、users/showの画面で、ユーザー二人目を見てる。

###users/showに追加
deviseでは、user/showは、作られない。だからuser/showをroutesとコントール、viewを付け加える。

デザインは、無視して表示だけ書きます。

app/view/users/show
   <%= render 'follow_form' %>
   <%= render 'stats' %>

app/users/showの説明
renderで他のところから持ってくる。

一つ目のフォローしている人数とフォローされている人数を示す表示。

その数字を押すと、フォローしている、フォローされている人の一覧が出てくる画面を作っていく。

app/views/users/_stats.html.erb
 <% @user ||= current_user %>
<div class="stats">
  <a href="<%= following_user_path(@user) %>">
    <strong id="following" class="stat">
      <%= @user.followings.count %>
    </strong>
    following
  </a>
  <a href="<%= followers_user_path(@user) %>">
    <strong id="followers" class="stat">
      <%= @user.followers.count %>
    </strong>
    followers
  </a>
</div>

app/views/users/_stats.html.erbの説明
この画面で、フォローしている人数とフォローされている人数を表示する。<%= following_user_path(@user) %><%= followers_user_path(@user) %>のリンクがある。これらの二つに対応するcontrollerとviewを作って行く。

app/controllers/users_controller.rb
  def following
      @user  = User.find(params[:id])
      @users = @user.followings
      render 'show_follow'
  end

  def followers
    @user  = User.find(params[:id])
    @users = @user.followers
    render 'show_follower'
  end
app/views/users/show_follow.html.erb
<% @user.followings.each do |user| %>
<table>
<tr>
  <td>  <%= user.username %> </td>
  <td><%= link_to '詳細', user_path(user) %></td>
</tr>

</table>
<% end %>

app/views/users/show_follow.html.erbの説明
  フォローしている人の名前の一覧の画面

app/views/users/show_follower.html.erb
 <% @user.followers.each do |user| %>
<table>
<tr>
  <td>  <%= user.username %> </td>
  <td><%= link_to '詳細', user_path(user) %></td>
</tr>

</table>
<% end %>

app/views/users/show_follower.html.erbの説明
フォローされている人の一覧画面

####補足説明 routesは、これでやっています。

config/routes.rb
  resources :users do
    member do
     get :following, :followers
    end
  end

これで、フォローしている人数とフォローされている人数をカウント表示と一覧は完成です。

###二つ目の機能を作る。他のユーザーのフォロー、フォローを解除する。

config/roures.rb
   resources :relationships, only: [:create, :destroy]
app/views/users/_follow_form.html.erb
 <% unless current_user?(@user) %>
  <div id="follow_form">
  <% if current_user.following?(@user) %>
    <%= render 'unfollow' %>
  <% else %>
    <%= render 'follow' %>
  <% end %>
  </div>
<% end %>  
app/helpers/users_helper.rb
  def current_user?(user)
     user == current_user
  end

app/views/users/_follow_form.html.erbの説明
 一行目<% unless current_user?(@user) %>
このコードで、現在ログインしているユーザーのプロフィールは、フォロー、フォロー解除のボタンが出ないようにする。

三行目からのifの説明。
ユーザーがフォローしている場合は、フォロー解除ボタンを表示。
してない場合は、フォローボタン表示させる。

###フォローボタン、フォロー解除のボタンの機能

app/views/users/_unfollow.html.erb
<%= form_for(current_user.following_relationships.find_by(following_id: @user.id), html: { method: :delete }) do |f| %>
  <%= f.submit "Unfollow", class: "btn btn-large follow-btn" %>
<% end %>
app/views/users/_follow.html.erb
 <%= form_for(current_user.following_relationships.build(following_id: @user.id)) do |f| %>
  <div><%= f.hidden_field :following_id %></div>
  <%= f.submit "Follow", class: "btn btn-large btn-primary follow-btn" %>
<% end %>
app/controllers/relationships_controller.rb
class RelationshipsController < ApplicationController
  
   def create
    @user = User.find(params[:relationship][:following_id])
    current_user.follow!(@user)
    redirect_to @user
  end

  def destroy
    @user = Relationship.find(params[:id]).following
    current_user.unfollow!(@user)
    redirect_to @user
  end
end

これで完成。

113
123
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
113
123

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?