前回の記事に続き、またハマりました。
ハマったところ
Follow機能とUnfollow機能のバックエンドの実装部分。
すでにビューの部分(Followボタン、Unfollowボタン)はできている。
コントローラーでUnfollowされるユーザー情報を取得するところに疑問が生まれ、
考え込んでしまった。
controllerに、ユーザーをFollowするcreateアクションと
Unfollowするdestroyアクションを追加するのですが、そのアクションの中身の部分です。
以下にコード示します。
疑問になったコード
class RelationshipsController < ApplicationController
before_action :logged_in_user
def create
user = User.find(params[:followed_id])
current_user.follow(user)
redirect_to user
end
def destroy
user = Relationship.find(params[:id]).followed
current_user.unfollow(user)
redirect_to user
end
end
上記コードのdestroy
アクションでは
user = Relationship.find(params[:id]).followed
で変数user
を取得し、unfollow
メソッドの引数として利用しています。
URLに含まれているparams[:id]
でRelationshipモデルのidを検索しているんです。
え、なんで?① followed_id
を検索するところじゃないの??
え、なんで?② find(params[:id])
ってparams[:id]
でfollowed_id
カラムを検索するって意味だっけ??
目には見えないrelationshipモデルを取り巻く情報の流れが頭に構築できていなかったんですね。
次の項で解決に至った箇所を示します。
viewファイルのerb(埋め込みルビー)が解決の糸口に
Unfollowボタンを表示するパーシャルコードを以下に示します。
<%= form_for(current_user.active_relationships.find_by(followed_id: @user.id),
html: { method: :delete }) do |f| %>
<%= f.submit "Unfollow", class: "btn" %>
<% end %>
このコードが生成するHTMLは以下です。
<form class="edit_relationship" id="edit_relationship_90" action="/relationships/90" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="_method" value="delete">
<input type="hidden" name="authenticity_token" value="RRvQ5/IIXUuXjUCJzhpDrXBtFOZ6gTHkonrkOn3wFO4SJPNMPwTESu0+8dB+QeSfI8+14AUbgLDOzRalKq3YBw==">
<input type="submit" name="commit" value="Unfollow" class="btn" data-disable-with="Unfollow">
</form>
action=
の部分が/relationships/90
なのでparams[:id]=90
でdeleteメソッドすることになってます。
解決!
あー、followしたりunfollowしたりする度に、その関係性をRelationshipモデルに生成しているんですね。
FollowボタンとUnfollowボタンを押した場合、生成されるHTMLのaction属性は、1ずつ増えた:idを有するURLになっていました。
Unfollowの流れ
1.Unfollowボタンには、Relationshipモデルのidを含むURLをaction属性にもつHTMLがある
2.params[:id]をidにもつrelationshipを取り出す
3.followedメソッドで、フォローされているユーザーを取り出し、変数userへ代入
4.unfollowメソッドで現在ログインしているユーザーから、userをフォローしているというデータを削除
find(params[:id])じゃフォローしてるやつのデータ取り出せないだろう!と思ってしまったというお話でした。
Railsすごすぎ。