Rails × jquery  爆速でGoogleカレンダーつぽいアプリを作ってみよう（FullCalenderバージョン)

# 今日の目標
爆速でGoogleカレンダーっぽいアプリを作ってみる

[![Image from Gyazo](https://i.gyazo.com/3412fe5c04717ec7c0e17434856a0535.png)](https://gyazo.com/3412fe5c04717ec7c0e17434856a0535)

[FULLCalender公式ページ](https://fullcalendar.io/)


## 機能

- 月別、週別、日別の表示が可能

- イベントをドラッグして作成および編集が可能(今回は未実装)


+ Googleカレンダーとの同期もできる(今回は未実装)

今回は爆速バージョンということでイベントタイトル、説明、開始日、終了日を登録し、カレンダーに登録するところまでの実装とします。

## 環境
Ruby 2.5.1
Ruby on rails 5.2.4
Sqlite3 1.4.2

## gemの記載

Gemfileに使うgemを追加

```ruby:Gemfile
gem 'jquery-rails', '4.3.3'
gem 'fullcalendar-rails'
gem 'momentjs-rails'
```
bundle installを実行

## application.js

```javascript:assets/javascripts/application.js

//= require jquery
//= require moment
//= require fullcalendar
```
今回は単一機能のアプリであるので　application.jsに直書きします。

```javascript:assets/javascripts/application.js
$(function () {
    function eventCalendar() {
        return $('#calendar').fullCalendar({});
    };
    function clearCalendar() {
        $('#calendar').html('');
    };
});
```
一つ目の関数ではFullCalendarの設定を読み込み、二つ目の関数ではFullCalendarを削除します。
そして、RailsにはTurbolinksというツールを使ってページ遷移を高速にさせています。この機能がないと、Turbolinksを使っているときにカレンダーが複数回表示されることが起きてしまいます。

関数を追加したら、今度は呼び出すコードをfunction　clearCalender()の後ろに記述します。

```javascript:application.js
$(document).on('turbolinks:load', function () {
    eventCalendar();
});
$(document).on('turbolinks:before-cache', clearCalendar);
```
## application.css

*= require fullcalendarを追加

```css:assets/application.css
*= require_tree .
 *= require_self
 *= require fullcalendar
 */
```
これで、viewのerbファイルに`<div id="calendar"></div>`と書き込むだけでカレンダーが表示されます。(が、まだこれではイベント表示機能を付けた時に上手く表示されないときがあります。この後改修していきます。)
要ルーティングの設定。

## scaffoldで爆速でEventモデル、コントローラ等作成する
イベントにはタイトル、説明、開始日、終了日が必要です。
今回はscaffoldを用いて爆速でモデル、コントローラを作成します。

＊scaffoldを使うとCRUD機能を爆速で実装出来ます。（テストアプリ向け)

CRUD とは Create（作成） / Read（表示） / Update（更新） / Delete（削除） の略でアプリケーションを実現するために必要十分な機能群のことを指します。

そして、Rails の Scaffold を利用することによって、その CRUD を素早く実現できるので実際に試してみましょう。

```
$ rails g scaffold Event title:string description:text start_date:datetime end_date:datetime
```
マイグレーションファイルが以下のように作成されているか確認しましょう
[![Image from Gyazo](https://i.gyazo.com/43391bd2cf88180d606441216a47ff0c.png)](https://gyazo.com/43391bd2cf88180d606441216a47ff0c)

## ルーティング
scaffoldでモデル、コントローラを作成した後はルーティングを設定しましょう。

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :events
  
  root 'events#index'
end
```



## JSONファイルの作成
Fullcalendarにイベントの情報を表示するには、JSONファイルを使ってあげます。

JSONを渡すために、Railsのjbuilderというものを使っていきます。
scaffoldによってjson.jbuilderファイルが自動で作られています。

[![Image from Gyazo](https://i.gyazo.com/1e5ead539856390c95f8922973451246.png)](https://gyazo.com/1e5ead539856390c95f8922973451246)

ここに以下の記述を追加します。

```ruby:app/views/_event.json.jbuilder
json.array!(@events) do |event|
  json.extract! event, :id, :title, :description   
  json.start event.start_date   
  json.end event.end_date   
  json.url event_url(event, format: :html) 
end
```

## application.js
ここまでの記述のまとめ

```javascript:assets/javascripts/application.js

$(function () {
    function eventCalendar() {
        return $('#calendar').fullCalendar({});
    };
    function clearCalendar() {
        $('#calendar').html('');
    };
    $(document).on('turbolinks:load', function () {
    eventCalendar();
    });
    $(document).on('turbolinks:before-cache', clearCalendar);

    $('#calendar').fullCalendar({
    events: '/events.json'
    });
});
```
このままでも作動するのですが　若干turbo-linksの不具合が生じます。

```javascript

if ($('#calendar').length) {
   function eventCalendar() {
   return $('#calendar').fullCalendar({
    });
```
という形で　lengthを呼び出すことで、#calendarが存在していた場合はtrueの処理がされ、無い場合はnillを返すという記述をすることで　Turbo-linksが正常に動作するようになります。

## application.js

完成記述 オプションを付け加える場合には　基本的に以下の記述に追加する

```javascript

$(function () {
  $(document).on('turbolinks:load', function () {
    if ($('#calendar').length) {
      function eventCalendar() {
        return $('#calendar').fullCalendar({});
      };
      function clearCalendar() {
        $('#calendar').html('');
      };
      $(document).on('turbolinks:load', function () {
        eventCalendar();
      });
      $(document).on('turbolinks:before-cache', clearCalendar);

      $('#calendar').fullCalendar({
        events: '/events.json'
      });
    }
  });
});

```
Turbo-linksの記述位置に注意です。

見本完成形

[![Image from Gyazo](https://i.gyazo.com/4607c9d2027defc6259f1bb5de53983e.png)](https://gyazo.com/4607c9d2027defc6259f1bb5de53983e)


ドラッグ機能、Googleカレンダーとの同期も含め、オプションは豊富なので　是非研究してみてください。

公式ドキュメントを読み込む力は必須なのでこちらも読み込みましょう。

[公式ドキュメント](https://fullcalendar.io/docs/event-object)

オプション等の記事はまた次の機会に

[Keita Higaki](https://github.com/higakikeita)

[がっきーTwitter](https://twitter.com/keitah0322)