非同期通信について
ポイント4点
この4つだけ押さえていれば簡単に実装ができる
- 非同期する機能箇所の部分テンプレートを作る
- link_toをlocal: falseにしてjs形式で送信
- jsファイルを用意する
- controllerのredirect_toを消す
1.部分テンプレートファイルを用意する
- 部分テンプレートにすることで、view全体ではなく、指定した部分のみをリロードなしで返してくれる
_form.html.erb
<% if book.favorited_by?(current_user) %>
<td>
<%= link_to book_favorites_path(book), method: :delete do %>
🤍<%= book.favorites.count %>いいね
<% end %>
</td>
<% else %>
<td>
<%= link_to book_favorites_path(book), method: :post do %>
♡<%= book.favorites.count %>いいね
<% end %>
</td>
<% end %>
index.html.erb
<div class="favorites_buttons_<%= @book.id %>">
<%= render 'favorites/favorite.btn', book: @book %>
</div>
- class名をfavorites_buttonsにすると全ての投稿のいいねボタンが同じクラス名になってしまう
- 判別する方法として_<%= @book.id %>にて、どの投稿に対していいねをしたか判別
2.非同期の設定をする
- local: falseを設定することで、非同期処理が発生
_form.html.erb
<%= form_with model: [book, book_comment],local: false do |f| %>
<%= f.text_area :comment, rows: '5', cols: '50', placeholder: "コメントをここに", class: "comment-textarea" %>
<%= f.submit "送信" %>
<% end %>
3.jsファイルを用意する
escape_javascript
- JavaScriptファイル内にHTMLを挿入するときに実行結果をエスケープするために必要
create.js.erb
$('some_element').replaceWith('<%= escape_javascript render 'some/element_template' %>');
// 上記の短縮形
$('some_element').replaceWith('<%= j render 'some/element_template' %>');
4.controllerのredirect_toを消す
- redirect_to を省略することで、コントローラー名のjs.erbを探すことになる
favorites.controller.erb
def create
@book = Book.find(params[:book_id])
@favorite = current_user.favorites.new(book_id: @book.id)
@favorite.save
end