Railsチュートリアル第14章の 14.1.5 フォロワーの演題で盛大にハマったので備忘録を残します。
#14章でどんなことを勉強するのか
Railsチュートリアルでは、Twitteサービスのクローンを作っています。
第14章では、Twtterでいうところのfollowとfollowerの機能を実装しながら勉強します。
#どんなところではまったのか
フォローするユーザーとフォローされるユーザーを記録するために、
この章で扱うデータモデルの構成は、以下に示すような関係になっていました。
Userテーブル
id | name | |
---|---|---|
1 | foo | bar@bar.com |
↓ userテーブルのidとfollower_idをthroughで紐づけ
follower_id | followed_id |
---|---|
1 | 2 → |
1 | 3 → |
3 | 2 |
5 | 2 |
1 | 6 → |
2 | 2 |
↓ followed_idでuser.followingという配列を作成する
:has_many
id | name | |
---|---|---|
→2 | ... | ... |
id | name | |
---|---|---|
→3 | ... | ... |
id | name | |
---|---|---|
→6 | ... | ... |
##コードで表すと
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
上記の記述により、様々なメソッドが使えるようになります。
active_relationship.follower | フォロワーを返します |
---|---|
active_relationship.followed | フォローしているユーザーを返します |
user.active_relationships.create(followed_id: other_user.id) | userと紐付けて能動的関係を作成/登録する |
user.active_relationships.create!(followed_id: other_user.id) | userを紐付けて能動的関係を作成/登録する (失敗時にエラーを出力) |
user.active_relationships.build(followed_id: other_user.id) | userと紐付けた新しいRelationshipオブジェクトを返す |
Railsが作ってくれたメソッドに加えて、チュートリアルでは以下のようなメソッドも定義しました。
class User < ApplicationRecord
.
.
.
def feed
.
.
.
end
# ユーザーをフォローする
def follow(other_user)
following << other_user
end
# ユーザーをフォロー解除する
def unfollow(other_user)
active_relationships.find_by(followed_id: other_user.id).destroy
end
# 現在のユーザーがフォローしてたらtrueを返す
def following?(other_user)
following.include?(other_user)
end
private
.
.
.
end
#演習課題は?
やっとここまでこれました。以下問題文。
コンソールを開き、何人かのユーザーが最初のユーザーをフォローしている状況を作ってみてください。最初のユーザーをuserとすると、user.followers.map(&:id)の値はどのようになっているでしょうか?
1.コンソール開いて、適当な変数名(user1, user2, user3)にUserテーブルの適当な値(User.firstとか)を代入
2.user2.follow(user1)でもいいし、railsがつくった user1.active_relationships.create(user2)でもいいからフォローとフォロワーを作成
3.user1.followers.map(&:id)でfollowerになったuserのidを配列で出力
できない...。
** 原因 **
follower_idとRelationテーブルのヒモ付を間違えてた。
正しいコードは
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :followers, through: :passive_relationships, source: :follower
間違えたコード has_many の through: にactive_relationships渡してる...
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :followers, through: :active_relationships, source: :follower
解決まで時間かかりました。コードのミスって治すのが本当に難しいですね...
followメソッドが悪いのかな?user.active_relationships.createならいけるかも!とか
コンソールで試行錯誤したらこんな落ちでしたとさ!
Railsチュートリアル同じようにつまった人いたらこれが参考になりますように!