icalendar and Rails

I’ve recently used icalendar to output an ical from a Rails app I’m running. It’s incredibly simple, here’s what I did:

  1. Create an ical_controller:
    script/generate controller ical
  2. Add a method to generates the events:
    require 'icalendar'
    
    class IcalController < ApplicationController
    
      caches_page :competitions
    
      def competitions
        @cal = Icalendar::Calendar.new
    
        Competition.find_all.each do |comp|
          event = Icalendar::Event.new
          event.start = comp.date
          event.end = comp.date
          event.summary = comp.name
    
          @cal.add event
        end
      end
    
    end
  3. Create a view (app/views/ical/competitions.rhtml):
    < %= @cal.to_ical %>
  4. Install icalendar into your vendor directory:
    cd vendor
    gem unpack icalendar
  5. Add the necessary dependency to config/environment.rb
    require 'icalendar-0.96.4/lib/icalendar'

And that’s it. Once deployed you can access your ical and import it anywhere. I’ve tried mine out with Google Calendar and it imported without a hitch. One deficiency in icalendar is the inability to give a name or description to the calendar itself, so you’ll have to rename it in your calendar application. The only caveat in the above code is the caching directive in the controller. I’ve cached the entire page because the events don’t change frequently. To expire the cache you’ll have to add the following line to the appropriate controller methods where your events changes:

expire_page :controller => "ical", :action => "competitions"
Spread the word: Technorati related  |  Technorati related  |  del.icio.us bookmark it!  |  submit icalendar and Rails digg.com digg it!  |  reddit reddit!

8 Responses to “icalendar and Rails”

  1. smtm says:

    Have you figured out if it is possible to give the calendar a name?

    Did you have utf-8 type of issues. I am german sepaking and we have those umlauts and the calendar app (muzilla sunbird) is complaining and wont read the calendar..

  2. Miles says:

    It doesn’t look like the Ruby icalendar package supports names, and I can’t find anything in the RFC about calendar names. I know Google Calendar uses a field called ‘X-WR-CALNAME’, but I don’t know if it’s widespread. It should be trivial to add a name field that outputs that header if you want to.

    UTF-8 is trickier. I know Ruby doesn’t have the best support for it. Since everything I did was in English, I didn’t have any problems. You may want to take a look at this page:

    http://wiki.rubyonrails.org/rails/pages/HowToUseUnicodeStrings

    and the last comment:

    I just encountered a problem with a String containinung German umlauts (äöüß) and the scan method of the String class. I wanted to tokenize the string on word boundaries and tried the following:

    firstname, lastname = s.scan(/\w+/)

    This does not work; scan generated a new token each time it came across an umlaut. So I changed the call slightly:

    firstname, lastname = s.scan(/[^ ]+/)

    This works as expected.

    String#scan is Umlaut-aware for me on Ruby 1.8.4 when $KCODE is properly set to “u”.

  3. Psousa says:

    great mini-tutorial you wrote. thanks!

    have you managed to create a recurring event?

  4. Miles says:

    I haven’t tried to create a recurring event, but looking at the Event object it does support them. Keep in mind Event is just a data object, the recurrence fields are of type ‘icalmultiproperty’ (defined in component.rb). They are described as:

    # Define a set of methods defining a new property, which
    # supports multiple values for the same property name.

    but from reading the code it’s not obvious to me what to set those fields with. At a guess I’d say it just follows the format from the RFC, e.g.:

    Daily for 10 occurrences:
    
    DTSTART;TZID=US-Eastern:19970902T090000
    RRULE:FREQ=DAILY;COUNT=10
        ==> (1997 9:00 AM EDT) September 2-11
    

    Try setting the fields with values like that and see what gets outputted, or take an existing icalendar with a recurring event, parse it, then see what values are held in the fields. I’m sure the author would except a patch to extend the Event class to be able to handle friendly configuration of recurring events.

  5. Miles Barr » Blog Archive » Rails iCalendar improvement says:

    […] I came across this thread that simplifies the ical controller from my previous example. It correctly sets the content type header and removes the need for a template. The new version is: […]

  6. John beck says:

    Perhaps a little late to the party but I ran into the same problem. The solution I settled on worked slightly differently. I avoid the include and used the Icalendar namespace.

  7. Vijay says:

    Thanks for the post.
    Here, you are exporting iCal file , asking user to save file.
    How can we save this .ics file to particular folder in rails, say I want to save this .ics file to ‘/public/ics/’ folder in rails. ?

    how can we do this ?
    Any Idea ?

    thanks,

  8. Dev Blog AF83 » Blog Archive » Publishing ICalendar events with Ruby on Rails says:

    […] icalendar and Rails […]

Leave a Reply

Line and paragraph breaks automatic.
XHTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>