学習記録

アウトプット用に作りました

simple_calendarを使ってカレンダーを実装

gemのsimple_calendarをPFで使おうかなと考えているので、PFで実装する前に練習で使用してみることにしました。

GitHub - excid3/simple_calendar: A wonderfully simple calendar gem for Rails

使用方法

まず最初にGemfilesimple_calenderのgemを追加してbundle installしました。

gem "simple_calendar", "~> 2.4"

次にboardコントローラを作成します。

$ bundle exec rails generate controller boards index
Running via Spring preloader in process 13728
      create  app/controllers/boards_controller.rb
       route  get 'boards/index'
      invoke  erb
      create    app/views/boards
      create    app/views/boards/index.html.erb
      invoke  helper
      create    app/helpers/boards_helper.rb
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/boards.scss
class BoardsController < ApplicationController
  def index
    @boards = Board.all
  end
end

boardモデルを作成します。

$ bundle exec rails generate model board
Running via Spring preloader in process 13762
      invoke  active_record
      create    db/migrate/20210524125207_create_boards.rb
      create    app/models/board.rb

作成されたマイグレーションファイルに必要なカラムとデータ型を指定します。

class CreateBoards < ActiveRecord::Migration[6.1]
  def change
    create_table :boards do |t|
      t.string :title
      t.text :content
      t.datetime :start_time

      t.timestamps
    end
  end
end

t.datetime :start_timeこのカラムがカレンダーには必要です。日記を投稿したい日を選択するために使われます。

追記したらbundle exec rails db:migrateを行います。

$ bundle exec rails db:migrate
== 20210524125207 CreateBoards: migrating =====================================
-- create_table(:boards)
   -> 0.1614s
== 20210524125207 CreateBoards: migrated (0.1615s) ============================

カレンダーが表示されるようにビューを作成していきます。

<p id="notice"><%= notice %></p>

<h1>自分の日記</h1>

<%= month_calendar events: @boards do |date, boards| %>
  <%= date.day %>
<% end %>

f:id:kimura34:20210524233714p:plain

カレンダーのレイアウトを導入していきます。

$ bundle exec rails g simple_calendar:views
Running via Spring preloader in process 14313
      create  app/views/simple_calendar
      create  app/views/simple_calendar/_calendar.html.erb
      create  app/views/simple_calendar/_month_calendar.html.erb
      create  app/views/simple_calendar/_week_calendar.html.erb

これらの作成されたファイルを使うためにapplication.scssに下記の一番上の記述を追記します。

*= require simple_calendar
*= require_tree .
*= require_self

f:id:kimura34:20210524233803p:plain

このままではただのカレンダーを表示するだけのページになってしまっているので、日記作成、詳細ページ、編集、削除の機能を追加していきます。

まず最初に各アクションをルーティングとコントローラに追加します。

Rails.application.routes.draw do
  resources :boards
end
class BoardsController < ApplicationController
  def index
    @boards = Board.all
  end

  def new
    @board = Board.new
  end

  def show
    @board = Board.find(params[:id])
  end

  def create
    Board.create(board_params)
    redirect_to boards_path
  end

  def destroy
    @board = Board.find(params[:id])
    @board.destroy
    redirect_to boards_path, notice:"削除しました"
  end

  def edit
    @board = Board.find(params[:id])
  end

  def update
    @board = Board.find(params[:id])
    if @board.update(board_params)
      redirect_to boards_path, notice: "編集しました"
    else
      render 'edit'
    end
  end

  private

  def board_params
    params.require(:board).permit(:title, :content, :start_time)
  end

end

次にビューを編集して表示を変えていきます。各ビューファイルを用意しました。このビューファイルの中に

$ touch app/views/boards/edit.html.erb
$ touch app/views/boards/show.html.erb
$ touch app/views/boards/new.html.erb
show.html.erb

<p id="notice"><%= notice %></p>

<p>
  <strong>タイトル</strong>
  <%= @board.title %>
</p>

<p>
  <strong>時間</strong>
  <%= @board.start_time.strftime("%Y-%m-%d %H:%M") %>
</p>

<p>
  <strong>内容</strong>
  <%= @board.content %>
</p>

<%= link_to 'Edit', edit_board_path(@board) %> |
<%= link_to 'Back', boards_path %>
new.html.erb, edit.html.erb

<%= form_with(model: @board, local: true) do |f| %>

  <div class="title">
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>

    <div class="time">
    <%= f.label :start_time %>
    <%= f.datetime_select :start_time %>
  </div>

  <div class="content">
    <%= f.label :content %>
    <%= f.text_field :content %>
  </div>

  <div class="submit">
    <%= f.submit %>
  </div>

<% end %>
index.html.erb

<p id="notice"><%= notice %></p>

<h1>自分の日記</h1>

<table>
  <thead>
    <tr>
      <th>タイトル</th>
      <th>時間</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @boards.each do |board| %>
      <tr>
        <td><%= board.title %></td>
        <td><%= board.start_time.strftime("%Y-%m-%d %H:%M") %></td>
        <td><%= link_to 'Show', board %></td>
        <td><%= link_to 'Edit', edit_board_path(board.id) %></td>
        <td><%= link_to 'Destroy',board_path(board.id), method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to '日記をかく', new_board_path %>

<%= month_calendar events: @boards do |date, boards| %>
  <%= date.day %>

  <% boards.each do |board| %>
    <div>
      <%= link_to board.title, board %>
    </div>
  <% end %>
<% end %>

month_calendarの部分をweek_calendarにすると一週間分の表示になります。calendarのみだと4日分表示されました。

f:id:kimura34:20210524233841p:plain

カレンダーの日付の欄に日記詳細ページへのリンクを表示しています。

今回はマイグレーションファイルでカラムを作成した時にt.datetime :start_timeでカラムの型をdatetimeにしました。なので時間まで表示されてしまったので、日記としては少し不自然になってしまいました。時間までのデータはいらないのでt.date :start_timeで作ったほうがよかったなあと思いました。

参考 : 【rails】simple_calendarを使ってカレンダーつきのブログ機能を作ってみた。 - Qiita