モデルの作成を行う
-
Userモデルの中間テーブルとなるRelationshipモデルを作成する
-
カラムは、以下となります
follower_id : フォローしたユーザー
followed_id : フォローされたユーザー
$ rails g model Relationship follower:references followed:references
- 上記コマンド作成されたファイルに下記を追記
foreign_key: { to_table: :users }
(作成日時)_create_relationships.rb
class CreateRelationships < ActiveRecord::Migration[5.2]
def change
create_table :relationships do |t|
t.references :follower, foreign_key: { to_table: :users } #追記
t.references :followed, foreign_key: { to_table: :users } #追記
t.timestamps
end
end
end
- 修正後データベースへ反映
$ rails db:migrate
モデルの修正
- 先程作成したrelationshipモデルの修正を行っていきます
app/models/relationship.rb
class Relationship < ApplicationRecord
belongs_to :follower
belongs_to :followed
end
- モデル作成時に、カラムをreferences型にしていたので自動で外部キーが設定されている
- だが、上記の記述のままだと作成していない
followerテーブル
とfollowedテーブル
を参照しようとするのでclass_name: "User"
でuserテーブルからデータをとってくるように指定します。
models/relationship.rb
class Relationship < ApplicationRecord
belongs_to :follower, class_name: "User" #追記
belongs_to :followed, class_name: "User" #追記
end
- 続いてuserモデルを修正します
-
class_name: "Relationship"
でRelationshipテーブルを参照するよう記述します
models/user.rb
has_many :follower, class_name: "Relationship"
has_many :followed, class_name: "Relationship"
-
foreign_key
(外部キー)で参照するカラムを指定します
models/user.rb
class Relationship < 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
end
下記の
- フォローされる側、フォローしてくる側を取得しないといけないためthroughでスルーするテーブル、sourceで参照するカラムを指定。
models/user.rb
has_many :following_user, through: :follower, source: :followed # 自分がフォローしている人
has_many :follower_user, through: :followed, source: :follower # 自分をフォローしている人
- 最後に後ほど使用する定義を記述
models/user.rb
# フォローする
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
コントローラーの作成
$ rails g controller relationships
- 先程モデルに定義したメソッドを使用してコントローラーへ記述を行う
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
ルーティング
- 今回、userのidが必要なためrelationshipsをネストさせます
- memberを使って、別のルーティングを追加します
config/routes.rb
resources :users, only:[:index, :show, :edit, :update] do
member do
get :follows, :followers
end
resource :relationships, only: [:create, :destroy]
end
ビュー
ボタンを作成したい箇所に下記を記述
<% if current_user.following?(@user) %>
<%= link_to 'フォロー外す', user_relationships_path(@user.id), method: :delete, class: "btn-sm btn-danger" %>
<% else %>
<%= link_to 'フォローする', user_relationships_path(@user.id), method: :POST, class:"btn-sm btn-success" %>
<% end %>
- 以上で機能は完成です