event_calendar プラグインを使って Rails でイケてるカレンダーを実装してみた

はじめに

Rails3.2 で開発しているアプリにカレンダーを追加したい。それも、プロトタイプをサクッと作りたいので、プラグインを使ってみる。

カレンダーを実装するプラグインでは、Ruby Toolbox によると event_calendar が人気のようだ。

これでいってみよう。

event_calendar プラグインをインストール

Gemfile に event_calendar を追加。

gem 'event-calendar', :require => 'event_calendar'

そして

bundle

で gem をインストール。

ジェネレータを実行

Rails3.2 のデフォルトの JavaScript フレームワークjQuery だけど、event_calendar はデフォルトでは prototype.js 用のソースコードを出力してしまう。

対策としては、jQuery 用のオプションがあるので、それを指定すれば OK。

bundle exec rails g event_calendar --use-jquery

マイグレーションを実行

ユーザーごとにスケジュールを管理したいので、user_id 列を追加する。

class CreateEvents < ActiveRecord::Migration
  def self.up
    create_table :events do |t|
      t.integer   :user_id,   :null => false # 追加
      t.string    :name,      :null => false
      t.datetime  :start_at,  :null => false
      t.datetime  :end_at,    :null => false
      
      t.timestamps
    end
  end

  def self.down
    drop_table :events
  end
end

スケジュールといっておきながら、クラス名に Event とあるけど、これは event_calenar のデフォルト。ジェネレータのオプションで、モデル名とコントロール名を指定できるけど、面倒だったのでそのままにしておいた。

マイグレーションを実行してテーブルを作成。

bundle exec rake db:migrate

ログインユーザーのスケジュールを表示できるように修正

user_id 列を追加したので、Event クラスと User クラスを関連付けておく。User は devise で使っているやつ。

class Event < ActiveRecord::Base
  has_event_calendar

  attr_protected :user_id

  belongs_to :user
end

ログインユーザーで絞り込んで表示するように、コントローラーを修正。

class CalendarController < MainController
  before_filter :authenticate_user!

  # カレンダーを表示
  def index
    @month = (params[:month] || (Time.zone || Time).now.month).to_i
    @year = (params[:year] || (Time.zone || Time).now.year).to_i
    @shown_month = Date.civil(@year, @month)

    # ログインユーザーで絞り込む
    @event_strips = Event.event_strips_for_month(
      @shown_month,
      0,
      :conditions => { :user_id => current_user.id })
  end
  
end

:conditions オプションの存在はソースコード読まないと気づかないと思う。

動作確認

bundle exec rails s

でサーバーを起動し、カレンダーを表示。

まとめ

event_calendar プラグインを使って、良い感じの概観のカレンダーを手軽に作成できた。配色が Twitter Bootstrap に合ってる気がする。

evetn_calendar プラグインでは、サーバー側でカレンダーを生成するので、表示するスケジュールの数が多くなると当然遅くなる。ただ、ログインユーザーで絞り込むから、多くてもせいぜい数十件だと思う。1人のユーザーが1ヵ月で数百件もスケジュール入れたりしないはず。多分。

あと、ジェネレータではスケジュールの登録・編集は生成されないから、後でちゃんと実装しないとな。