14
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails で簡単にカレンダーを扱える simple_calendar で週表示カレンダーのフォーム作成を試す

Posted at

はじめに

Rails でカレンダーを簡単に取り扱えそうな simple_calendar という gem の存在を知りました。

そこで、週表示のカレンダーで、それぞれの日に予定を入れるフォームを作るとどんな感じになるか、サンプルを作りながら検証しました。

view は読みやすくするために haml も導入して試そうと思います。

環境の前提

  • Rails 5.1.6
  • ruby 2.4.3

目標

下記のような、日毎に入力フォームがある週表示カレンダーの作成を目指します。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3232323033302f33393063663362642d353836372d653762392d383265372d3139333462633330653130332e706e67.png

手順

1. 初期設定

rails アプリケーション新規作成

以下コマンドを実行します。

$ rails new calendar-sample
$ cd calendar-sample

Gem インストール

今回利用する simple_calendar, haml-rails をインストールします。

Gemfile
# 追記
gem 'simple_calendar', '~> 2.0'
gem 'haml-rails'
$ bundle

simple_calendar の view テンプレートを生成

あとから simple_calendar のデザインを修正できるように、テンプレートを生成します。

$ rails g simple_calendar:views

haml に変換

haml-rails のコマンドで haml に変換します。

$ rake haml:erb2haml

サンプル Model作成

表示確認用の Meeting モデルを scaffold で作成します。

$ rails g scaffold Meeting name start_time:date content:string

simple_calendar のカレンダー表示設定

週表示でカレンダーを表示できるよう、simple_calendar を設定します。

app/views/meetings/index.html.haml
-# 追記
= week_calendar do |date| 
  = date

表示確認

Migrateしてサーバを起動します。

$ rails db:migrate
$ rails s

http://localhost:3000/meetings にアクセスし、週表示カレンダーが表示されていることを確認します。

Screen Shot 2018-06-30 at 11.45.41.png

2. カレンダーのフォーム作成

route 登録

一括でデータ登録用のメソッドを routes に定義に定義します。

config/routes.rb
Rails.application.routes.draw do
  resources :meetings do
    collection do
      post :update_week
    end
  end
end

view 実装

日毎に content が入力できるようなフォームを実装します。

app/views/meetings/index.html.haml
-# 以下に書き換え
%h1 Week Meetings

= form_for :meeting, url: update_week_meetings_path, html: { method: :post } do
  = week_calendar do |date|
    = date
    - meeting = @meetings.find_or_initialize_by(start_time: date)
    - if meeting.id.nil?
      %p
        = hidden_field_tag "meeting[#{date}][start_time]", date
      %p
        = text_field_tag "meeting[#{date}][content]"
    - else
      = fields_for "meeting[]", meeting do |meeting_fields|
        %p
          = meeting_fields.hidden_field :start_time
        %p
          = meeting_fields.text_field :content
  = submit_tag

メソッドに find_or_initialize_by を使うことで、レコードの新規作成・編集どちらにも対応できるようにしています。

また、 meeting.id の有無で処理を分岐させていますが、これはクエリパラメータの形を統一するためです。

既存データはidをキーとしたハッシュで格納されるのに対し、新規データはidがないのでハッシュの配列で格納されます。

idがある場合

 "meeting"=>
  {"1"=>{"start_time"=>"2018-07-02", "content"=>"A"},
   "2"=>{"start_time"=>"2018-07-03", "content"=>"B"}}

idがない場合

 "meeting"=>
  [{"start_time"=>"2018-07-02", "content"=>""},
   {"start_time"=>"2018-07-03", "content"=>""}]

そのため、配列が入ったクエリパラメータをPOSTしようとすると下記エラーが生じるため、ハッシュを使う形に統一できるようにしています。

Rack::QueryParser::ParameterTypeError (expected Hash (got Array) for param `meeting'):

参考URL

controller 設定

view で入力された複数日のデータを一括で登録・更新するためのメソッドを実装します。

app/controllers/meetings_controller.rb
  # 追記
  def update_week
    week_meetings_params.keys.each do |key|
      @meeting = Meeting.find_or_initialize_by(start_time: week_meetings_params[key][:start_time].to_date)
      @meeting.update_attributes(week_meetings_params[key])
    end
    redirect_to meetings_path
  end

  # 中略...

  private
    # 追記
    def week_meetings_params
      params.require(:meeting).permit!
    end

http://localhost:3000/meetings にアクセスし、週ごとのフォームが更新できることを確認します。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3232323033302f33393063663362642d353836372d653762392d383265372d3139333462633330653130332e706e67.png

終わりに

突貫で作成したサンプルなので粗い部分もあるかと思いますが、simple_calendar を使った週表示のフォームを試すことが出来ました。カレンダー部分の処理をシンプルに取り扱えて便利だなと思いました。

参考URL

14
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?