simple_calendarを使ってカレンダーを実装
gemのsimple_calendar
をPFで使おうかなと考えているので、PFで実装する前に練習で使用してみることにしました。
GitHub - excid3/simple_calendar: A wonderfully simple calendar gem for Rails
使用方法
まず最初にGemfile
にsimple_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 %>
カレンダーのレイアウトを導入していきます。
$ 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
このままではただのカレンダーを表示するだけのページになってしまっているので、日記作成、詳細ページ、編集、削除の機能を追加していきます。
まず最初に各アクションをルーティングとコントローラに追加します。
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日分表示されました。
カレンダーの日付の欄に日記詳細ページへのリンクを表示しています。
今回はマイグレーションファイルでカラムを作成した時にt.datetime :start_time
でカラムの型をdatetimeにしました。なので時間まで表示されてしまったので、日記としては少し不自然になってしまいました。時間までのデータはいらないのでt.date :start_time
で作ったほうがよかったなあと思いました。