かなり自分用。アウトプットしないと忘れそうなので記録。分かりやすくはない。
def change
create_table :relationships do |t|
t.integer :follower_id
t.integer :followed_id
t.timestamps
end
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
#userテーブル→relationテーブル
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
#relationテーブル→followedテーブル、followed_idを持って来る
has_many :followings, through: :relationships, source: :followed
#followerテーブル(本当はuser)→re_relationテーブル(本当relation)へfollowed_idを送る(参照)
has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id",
dependent: :destroy
#re_relationテーブル→userテーブルへfollower_idを持って来る
has_many :followers, through: :reverse_of_relationships, source: :follower
def follow(user_id)
relationships.create(followed_id: user_id)
end
def unfollow(user_id)
relationships.find_by(followed_id: user_id).destroy
end
def following?(user)
followings.include?(user)
end
resources :users, only: [:show,:index,:edit,:update] do
resources :relationships, only: [:create, :destroy] do
member do
get 'following' => 'relationships#followings', as: 'followings'
get 'followers' => 'relationships#followers', as: 'followers'
end
end
end
#menberよりcollectionのほうがいかも
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
<% users.each do |user| %>
<tr>
<td>
フォロー数:<%= user.followings.count %>
</td>
<td>
フォロワー数:<%= user.followers.count %>
</td>
<td>
<% unless user == current_user %>
<% if current_user.following?(user) %>
<%= link_to 'unfollow', user_relationship_path(user.id, current_user.id), method: :delete %>
<% else %>
<%= link_to 'follow', user_relationships_path(user.id), method: :post %>
<% end %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
説明
1行目のrelationshipsはフォローした時にそのカラムを新規保存するときに使う。
relationship = relationships.new(followed_id: user_id)
relationship.save
イメージはこんな感じ
2行目のfollowingsは@user = User.find(params[:id])
で特定のuser_idを抽としたときに@user.followings
で@userのフォロワー一覧が出せる。
1、2行目はusersテーブル→relationshipsテーブル→usersテーブルのフォローする人の一連の流れを表している
3、4行目はusersテーブル→relationshipsテーブル→usersテーブルのフォローされる人の一連の流れを表している
1行目はUserテーブルからrelationshipsテーブルに値を受け渡すための文。
例えばUser.find(1).relationshipsの記載だとUserid1なのでrelationshipsのfollower_idが1のrelationshipsのidが返される。
2行目がカラム→Viewにカラムを渡す時の文。
例えばUserのid1の人のフォロー『されてる』人を参照したいときはUser.followingsとやれば「follower_idが1」のfollowed_idを全部持ってきて!となり、User_id1の人のフォローされてる人をviewに持ってこれる
自分メモ
followers, through: :reverse_of_relationships, source: :followed
は
followersからreverse_of_relationshipsを通ってfollowedを持って来るという意味。sourceは持って来る側だから定義しているものの逆を書くイメージ。私は逆で認識してた。あとuserに対してfollowingsとやると沢山のfollowed_idが現れること。多対多ということを忘れず!!