【Rails】カレンダーの月めくりajax化


環境

Ruby 2.6.3
Rails 5.2.6
本番環境 Nginx/Puma/Linux2/AWS EC2/MySQL

この記事でわかる事

simple_calendarを実装させましたが、月を翌月や先月に切り替えるとリロードをしてしまうので
カレンダーのみ非同期で更新させる方法を解説します。

※simple_calendarの実装は以下記事を参考にさせていただきました。
【rails】simple_calendarを使ってカレンダーつきのブログ機能を作ってみた。
【Rails】simple_calendarを使ってカレンダーつきのmemo機能を作る。

実装方法

非同期処理のざっくり手順

  1. 更新トリガーを remote :trueにする
  2. 更新させたいviewを部分テンプレート化する
  3. アクション名.js.erbファイルを作り、更新処理を書く

↓参考記事↓
【Rails】 remote: trueでフォーム送信をAjax実装する方法とは?

解説

①更新トリガーを remote :trueにする

formやlink_toでcontrollerアクションを呼ぶトリガーの後ろの方にかくlocal:trueの場合は remote:trueにします。
今回はsimple_calendarで自動で生成されたview内にある月のlink_toを変更します。

view/simple_calendar/_month_calendar.html.erb
:
 <%= link_to t('simple_calendar.previous', default: '<<先月'), calendar.url_for_previous_view, remote: true %>
:

②更新させたいviewを部分テンプレート化する

カレンダーを更新させたいのでテンプレート化します。

_calendar.html.erb
 <%= month_calendar events: logs do |date, logs| %>
	<%= date.day %>
	<% logs.each do |logs| %>
     <div>
	   <i class="fas fa-tint text-primary"></i>
	   <span><%= logs.created_at.strftime('%H:%M') %></span>
     </div>
	<% end %>
<% end %>

部分テンプレートを呼び出しているviewはこのようになっています。↓↓↓
ここでdivにidを付けないと.js.erbで呼び出せないです

show.html.erb
:
  <div id="calendar">
    <%= render 'calendar', logs: @logs %>
  </div>
:

③アクション名.js.erbファイルを作り、更新処理を書く

showアクションでviewを呼び出しているのでshow.js.erbを作成します。
$('#id名').html("<%= j(renderで呼び出している箇所と同じもの) %>");
と書くので実際に書いて見るとこのようになります。

show.js.erb
$('#calendar').html("<%= j(render 'calendar', logs: @logs) %>");

これで月のカレンダーをめくった際に、ページ全体ではなくカレンダーのみを更新できました!