##概要
現在DMMWEBCAMPというプログラミングスクールで学習しておりまして、
ポートフォリオ作成にあたりイベントテーブルを作成してカレンダーに表示させました。
これから作成する方のお役に立てればと思います。
##参考にさせて頂いた記事
【Rails】Simple Calendarを使ったカレンダー表示
https://qiita.com/mikaku/items/0971442a7308dc669122
github
https://github.com/excid3/simple_calendar
##事前準備
・data_and_timeがスタートする日時
・meetingfinishtimeが終了する日時
####アソシエーション
class Event < ApplicationRecord
has_many :event_participates, dependent: :destroy
end
class EventParticipate < ApplicationRecord
belongs_to :event
end
##gem install
gem 'simple_calendar', '~>2.0'
$ bundle install
##Simple calendarのViewインストール
$ rails g simple_calendar:views
・views/simple_calendar内に3種類のカレンダーの雛形が出来ます。
####application.scss(CSS)への記載
*= require simple_calendar
*= require_tree .
*= require_self
##start_time end_timeの定義
class Event < ApplicationRecord
has_many :event_participates, dependent: :destroy
def start_time
self.date_and_time
end
def end_time
self.meetingfinishtime
end
end
このgemではstart_timeとend_timeの定義が必要です。(特にstart_time)
作成しているカラムが最初からその名前であれば良いのですが、違うカラム名なのであればモデルの方で定義しましょう。ただし日付と時刻を扱うのでデータ型は恐らくdatetime型でなければならないと思います。
最初定義せずに実装したところエラーが出ました。
githubではscaffoldを使用して最初から上記名称でカラムを作成しておりました。
##カレンダーの表示
私のポートフォリオ
</div>
<div class= 'calender'>
<%= month_calendar events: @events do |date, event| %>
<%= date %>
<% event.each do |event| %>
<br>
<% if user_signed_in? %>
<% if event.user_id == current_user.id %>
<i class="fa fa-circle notification-circle" style="color: red;"></i>
<% end %>
<% end %>
<% if event.event_participates.where(user_id: current_user).exists? %>
<span class="participate">
<%= link_to event.title,event_path(event) %>
</span>
<% else %>
<span class="other">
<%= link_to event.title,event_path(event) %>
</span>
<% end %>
<% end %>
<% end %>
</div>
カレンダーの表示とイベントのタイトルだけであれば以下のみで良いです。
<div class= 'calender'>
<%= month_calendar events: @events do |date, event| %>
<%= date %>
<% event.each do |event| %>
<%= event.title %>
<% end %>
<% end %>
</div>
def index
@events = Event.all
end
コントローラーで定義しているEvent.allを@eventsに格納しカレンダーで表示しています。
<%= month_calendar events: @events
この構文の中のevents:は恐らく変えるとエラーが出ますが、インスタンス変数は情報が格納されていればどんなものを使用しても大丈夫だと思います。
現在は先ほどインストールしたmonth_calendarを使用していますが、他に2つテンプレートが用意されているので3種類から使用することが出来るようです。
私は参加(participate)アクションを取っていればbackground-colorをオレンジに、
主催しているイベントであれば赤丸のアイコンを付けたかったので以下のような条件分岐を
カレンダー内で行いました。
<% if event.user_id == current_user.id %>
<i class="fa fa-circle notification-circle" style="color: red;"></i>
<% end %>
イベントテーブルの中のuser_id(つまりイベント作成者)が自分であればイベントタイトルの前にfont awesomeのアイコンを表示というものです。インライン要素のものであればここは何でも良いと思います。
次に
<% if event.event_participates.where(user_id: current_user).exists? %>
<span class="participate">
<%= link_to event.title,event_path(event) %>
</span>
<% else %>
<span class="other">
<%= link_to event.title,event_path(event) %>
</span>
<% end %>
1行目の <% if event.event_participates.where(user_id: current_user).exists? %>で
eventに参加(participete)するユーザーの中に自分(current_user)が存在しているかどうかを探しています。
見つかればclass participate、そうでなければclass otherとすることで、
表示する情報は同じでもclass名が違うという状態にすることが出来ました。
後はCSSで色を変えていくだけなので、皆さんのお好みのようにしていただければと思います。
ちなみにmonth_calenderのviewは以下です。
<div class="simple-calendar">
<p class="carendar-title"><%= "#{Date.today.month}月のイベントスケジュール" %></p>
<div class="calendar-heading" data-turbolinks="false">
<!--%= link_to t('simple_calendar.previous', default: 'Previous'), calendar.url_for_previous_view %-->
<!-- <span class="calendar-title"><%= t('date.month_names')[start_date.month] %> <%= start_date.year %></span> -->
<!--%= link_to t('simple_calendar.next', default: 'Next'), calendar.url_for_next_view %-->
<i class="fa fa-circle notification-circle" style="color: red;"><span>主催イベント</span></i>
<span class="calendar-info">参加予定</span>
</div>
<table class="table table-striped calendar-table">
<thead>
<tr>
<% date_range.slice(0, 7).each do |day| %>
<th><%= t('date.abbr_day_names')[day.wday] %></th>
<% end %>
</tr>
</thead>
<tbody>
<% date_range.each_slice(7) do |week| %>
<tr>
<% week.each do |day| %>
<%= content_tag :td, class: calendar.td_classes_for(day) do %>
<% if defined?(Haml) && respond_to?(:block_is_haml?) && block_is_haml?(passed_block) %>
<% capture_haml(day, sorted_events.fetch(day, []), &passed_block) %>
<% else %>
<% passed_block.call day, sorted_events.fetch(day, []) %>
<% end %>
<% end %>
<% end %>
</tr>
<% end %>
</tbody>
</table>
</div>
私のポートフォリオの仕様で上の部分をコメントアウトしています。
コメントアウトの場所に本来であれば次月や前月へのリンクが出てきます。
細かいところであれば柔軟に変えれそうです。
##まとめ
最初はfullcalendarでの実装を目論んだのですが、理解が及ばず諦めて今回こちらのgemを使用しました。イベントタイトルがstart_timeとend_timeの間で毎回出てしまうことを改善できればと思ったのですが私の力不足で難しかったです。
要素のclass名に特に意味はありません。スペルを所々間違えてますが、、
このぐらい簡単なカレンダーでも見せ方次第で私のものよりもっといいものになると思うので是非やってみてください。