iCal support for Rails
I’ve been pretty busy this week making a ton of headway on a significant project. Said project has support for both events and contacts within it and it made a lot of sense to let users get these out seamlessly to other applications. I’ll write about the vCard support tomorrow and will focus on calendar support tonight.
I’d used the iCalendar gem before so it was only a matter of minutes to get it up and running with my application. In brief, here’s how I would suggest using it.
Add an ical method to the model that will be exporting events. You’ll need to require ‘icalendar’ in order to get access to that class within your model. Here’s an example of the mapping I did between my object and the Icalendar::Event.
def ical e=Icalendar::Event.new e.uid=self.uid e.dtstart=DateTime.civil(self.date_start.year, self.date_start.month, self.date_start.day, self.date_start.hour, self.date_start.min) e.dtend=DateTime.civil(self.date_end.year, self.date_end.month, self.date_end.day, self.date_end.hour, self.date_end.min) e.summary=self.name e.created=self.created_at e.url=self.url e.last_modified=self.updated_at e end
Take notice of the UID field. You’ll want to ensure you have some sort of permanent UID identifying your event in the application so that subsequent exports (or RSS feeds) of the event will be updates.
You’ll want to handle the request to export the event in your controller. You could map it to the show method, but in my case, I added an export method.
def export @event=Event.where(:id => params[:id]).first respond_to do |format| format.ics end end
You’ll notice that the format is set to ics, the extension for a calendar file. You’ll need to make a modification to your config/initializers/mime_types.rb to add ICS support, like so:
Mime::Type.register_alias "text/calendar", :ics
Finally, in order to send the event to a calendar file, you’ll need add a view for the export method (in my case views/events/export.ics).
<% @calendar=Icalendar::Calendar.new %> <% @calendar.add @event.ical %> <% @calendar.publish %> <%= @calendar.to_ical %>
That’s all there is to it – it’s really dead simple and should be an easy addition to any app. You can see how you might expand on this to share entire calendar feeds rather easily.