メモ
rails 5.0.0
ログイン機能は、deviseで作っている。
###フォロー機能つける前の状態
deviseで、userモデルを作っている。パスワード以下の項目は省略
id | 名前 | メールアドレス |
---|---|---|
1 | 山田 | yamada@yahoo.co.jp |
2 | 佐藤 | satouu@gmail.com |
3 | 山本 | 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をセットで一意にする。
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
をできるようにする)
has_many :following_relationships, foreign_key: "follower_id", class_name: "Relationship", dependent: :destroy
relationships.following
をできるようにする。
belongs_to :following, class_name: "User"
validates :following_id, presence: true
1対多の関係になる。
###フォローしているユーザーを取り出す (user.followings
をできるようにする)
has_many :following_relationships, foreign_key: "follower_id", class_name: "Relationship", dependent: :destroy
has_many :followings, through: :following_relationships
belongs_to :follower, class_name: "User"
belongs_to :following, class_name: "User"
validates :follower_id, presence: true
validates :following_id, presence: true
###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
をできるようにする)
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
###フォロー機能のルーティング
resources :users do
member do
get :following, :followers
end
end
resources :relationships, only: [:create, :destroy]
###users/showに、追加
フォローするために、各ユーザーに二つの機能をつける。一つ目は、フォローしている人数とフォローされている人数を示す表示。その数字を押すと、フォローしている/フォローされている人の一覧が出てくる。
二つ目は、このユーザーをフォローする/フォロー解除のボタンである。
写真の説明
一人目のユーザーでログインしている。一つ目のユーザーが、users/showの画面で、ユーザー二人目を見てる。
###users/showに追加
deviseでは、user/showは、作られない。だからuser/showをroutesとコントール、viewを付け加える。
デザインは、無視して表示だけ書きます。
<%= render 'follow_form' %>
<%= render 'stats' %>
app/users/showの説明
renderで他のところから持ってくる。
一つ目のフォローしている人数とフォローされている人数を示す表示。
その数字を押すと、フォローしている、フォローされている人の一覧が出てくる画面を作っていく。
<% @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を作って行く。
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
<% @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の説明
フォローしている人の名前の一覧の画面
<% @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は、これでやっています。
resources :users do
member do
get :following, :followers
end
end
これで、フォローしている人数とフォローされている人数をカウント表示と一覧は完成です。
###二つ目の機能を作る。他のユーザーのフォロー、フォローを解除する。
resources :relationships, only: [:create, :destroy]
<% unless current_user?(@user) %>
<div id="follow_form">
<% if current_user.following?(@user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
def current_user?(user)
user == current_user
end
app/views/users/_follow_form.html.erbの説明
一行目<% unless current_user?(@user) %>
このコードで、現在ログインしているユーザーのプロフィールは、フォロー、フォロー解除のボタンが出ないようにする。
三行目からのifの説明。
ユーザーがフォローしている場合は、フォロー解除ボタンを表示。
してない場合は、フォローボタン表示させる。
###フォローボタン、フォロー解除のボタンの機能
<%= 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 %>
<%= 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 %>
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
これで完成。