af83

Publishing ICalendar events with Ruby on Rails

ICalendar is a standard (RFC 2445) for calendar data exchange. The standard is sometimes referred to as "iCal", which also is the name of the Apple, Inc. calendar program that provides one of the implementations of the standard. Source: ICalendar.

It's possible to generate ICalendar files with Ruby on Rails. This can be useful for letting users adding your events in their calendars.

The first step is the install of the icalendar gem: gem install icalendar. An alternative can be vpim.

Then, this library must be required from rails. Add require 'icalendar' to your config/environment.rb file. You can require it from elsewhre, but I think that config/environment.rb is a good place.

Here, we are ready to code our export of events fo .ics file. We suppose that we have an Events model:

class Event < ActiveRecord::Base
# Table name: events
#
#  id           :integer(11)     not null, primary key
#  title        :string(255)
#  date         :datetime
#  end_date     :datetime
#  summary      :text
#  content      :text
#  created_at   :datetime
#  updated_at   :datetime
end

We add a to_ics to this class:

# Convert to iCalendar
def to_ics
  event = Icalendar::Event.new
  event.start = self.date.strftime("%Y%m%dT%H%M%S")
  event.end = self.end_date.strftime("%Y%m%dT%H%M%S")
  event.summary = self.title
  event.description = self.summary
  event.location = 'Here !'
  event.klass = "PUBLIC"
  event.created = self.created_at
  event.last_modified = self.updated_at
  event.uid = event.url = "#{PUBLIC_URL}events/#{self.id}"
  event.add_comment("AF83 - Shake your digital, we do WowWare")
  event
end

Don't forget to declare PUBLIC_URL. I've done this declaration in config/environment/production.rb, so I can have different URL for development and production.

PUBLIC_URL = "http://my.site.com/"

The next part is modifying the show action of the EventsController to accept .ics format:

def show
  @event = Event.find(params[:id]})

  respond_to do |wants|
    wants.html
    wants.ics do
      calendar = Icalendar::Calendar.new
      calendar.add_event(@event.to_ics)
      calendar.publish
      render :text => calendar.to_ical
    end
  end
end

Note: the ics format is known by rails 2.0. If it was not the case, we could add it to config/initializes/mime_types.rb.

Add a link to your ical export and we are done:

<%= link_to @event.title, :controller => 'events', :action => :show, :format => :ics %>

You can now enjoy your icalendar events. There are some interresting links if you want more informations:

blog comments powered by Disqus