開発環境
Mac OS Catalina 10.15.7
ruby 2.6系
rails 6.0系
前提
・フォロー機能は実装済み(フォロー機能に関するgemは使用していません)
・フォロー機能を実装する際の中間テーブ名はrelationshipsテーブル
フォロー機能に関しては下記のURLの記事を参考に実装すると良いかと思います。
理解しやすくまとめてくれています。
https://qiita.com/mitsumitsu1128/items/e41e2ff37f143db81897
フォローボタン部分を部分テンプレートで切り出す
まずはフォローボタンを部分テンプレートで切り出します。
後にcreate.jsとdestroy.jsでこの部分テンプレートを差し替えるためです。
自分はsharedディレクトリを作っているので、その中に切り出しました。
# 自分はユーザー詳細ページにフォローボタンを設置しています。
<% if user_signed_in? && current_user.id != @user.id %>
<div>
<%= render "shared/follow", user: @user %>
</div>
<% end %>
<% if current_user.following?(user) %>
<%= form_for(current_user.relationships.find_by(follow_id: user.id), html: { method: :delete }) do |f| %>
<%= hidden_field_tag :follow_id, user.id %>
<%= f.submit 'フォロー解除', class: 'btn btn-danger btn-block' %>
<% end %>
<% else %>
<%= form_for(current_user.relationships.build) do |f| %>
<%= hidden_field_tag :follow_id, user.id %>
<%= f.submit 'フォローする', class: 'btn btn-primary btn-block' %>
<% end %>
<% end %>
切り出した部分テンプレートの親要素にIDを付与
後にjs.erbファイルでこのIDを取得して、中身を差し替えるためです。
<% if user_signed_in? && current_user.id != @user.id %>
# 下記1行にIDを付与
<div id="follow-ajax">
<%= render "shared/follow", user: @user %>
</div>
<% end %>
form_forをremote: trueにする
form_forをremote: trueにします。
form_forはform_withと異なり、デフォルトでremote: trueになっているわけではないので、非同期にしたい場合はremote: trueを記述してあげる必要があります。
# 次の1行にremote: trueを追加
<%= form_for(current_user.relationships.find_by(follow_id: user.id), html: { method: :delete },remote: true) do |f| %>
# 次の1行にremote: trueを追加
<%= form_for(current_user.relationships.build, remote: true) do |f| %>
コントローラーのリダイレクトの記述を削除
コントローラーでリダイレクトの記述をしている場合は削除します。
なければスルーで大丈夫です。
def create
following = current_user.follow(@user)
following.save
# リダイレクトの記述があれば削除する
end
def destroy
following = current_user.unfollow(@user)
following.destroy
# リダイレクトの記述があれば削除する
end
create.jsとdestroy.jsを編集する
どちらもコードは同じです。
前述のように自分はsharedディレクトリに部分テンプレートを入れているので、partialオプションの記述が'shared/follow'となります。
また、localsオプションで、切り出した部分テンプレート内で使う変数をしっかりと渡してあげましょう。
document.getElementById('follow-ajax').innerHTML = '<%= j(render partial: 'shared/follow', locals: { user: @user }) %>
document.getElementById('follow-ajax').innerHTML = '<%= j(render partial: 'shared/follow', locals: { user: @user }) %>
以上です。
参考になれば幸いです。