Fork

Reasons for this fork:

  • Fix compatibility with Rails >= 3.09 (https://github.com/dburkes/acts_as_event_owner/issues/14)
  • Use Bundler instead of Jeweler for gem releases (Jeweler appears to be abandoned)
  • Add CI via Travis

One test was failing for me, which I don’t have time to look into at the moment (event_specificiation_spec.rb) so I have marked it as pending.

ActsAsEventOwner

ActsAsEventOwner is an ActiveRecord extension that adds calendar event management to any ActiveRecord model. Models that declare themselves as acts_as_event_owner gain two has_many associations- one for the event specifications, and one for the event occurrences.

ActsAsEventOwner supports recurring events, with roughly the same recurrence rule capabilities as Apple’s iCal application. Under the hood, ActsAsEventOwner uses ri_cal to provide recurring event support.

Installation

Rails 2.3.x

ActsAsEventOwner is available both as a gem and as a plugin.

Installing as a Rails 2.3.x plugin

To install as a plugin, just do


  script/plugin install git://github.com/dburkes/acts_as_event_owner_.git

You’ll also need to install the ri_cal gem by the method of your choice (bundler, system gems, etc).

Installing as a Rails 2.3.x gem

To install as a gem, use your preferred method of gem installation, e.g. Bundler, config.gem, etc.

Rails 2.3.x post-installation steps

After installation, generate a migration to add ActsAsEventOwner tables to your database:


  script/generate acts_as_event_owner_migration
  rake db:migrate

If you want to use the acts_as_event_owner rake tasks, put the following in your Rakefile:


  if Gem.searcher.find('acts_as_event_owner')
    Dir["#{Gem.searcher.find('acts_as_event_owner').full_gem_path}/**/tasks/*.rake"].each { |ext| load ext }
  end

Rails 3

Just add it to your Gemfile, like so:


  gem 'acts_as_event_owner'

Then do:


  bundle install

Rails 3 post-installation steps

After installation, generate a migration to add ActsAsEventOwner tables to your database:


  rails generate acts_as_event_owner:migration
  rake db:migrate

Usage


  class User < ActiveRecord::Base
    acts_as_event_owner
  end

  @user = User.create :name => 'Alvin Seville'
  @user.event_specifications.create :description => 'acquire cheese balls',
    :start_at => Date.today.to_time,
    :repeat => :daily,
    :generate => false

  @user.events # => []

  @user.events.generate :from => Date.today.to_time, :to => Date.today.to_time + 1.week

  # override the description on a per-generate basis
  @user.events.generate :from => Date.today.to_time - 1.day, :to => Date.today.to_time + 1.week,
    :attributes => { :description => 'acquire cheese balls, like, right away!' }

  @user.events # => (8 ActsAsEventOwner::EventOccurrence objects)

  @user.events.past # => (1 ActsAsEventOwner::EventOccurrence objects)
  @user.events.upcoming #=> (7 ActsAsEventOwner::EventOccurrence objects)

Adding custom fields

You can create your own migrations to add custom fields to the event objects- just make sure that you add the same fields to both the event_specifications and event_occurrences tables.

When you create an EventSpecification, set the value of your custom fields, then, later, when you call generate, the values of those fields in the EventSpecification will be copied over to any generated EventOcurrence records.

Just like you can do with the standard :description attribute, you can override the default value of your custom fields with the :attributes parameter when you call generate.

Recurrence rules

ActsAsEventOwner supports recurrence rules roughly equivalent to those supported by Apple’s iCal application. Examples are:

One-time event


  EventSpecification.create :description => 'pick up laundry',
    :start_at => Time.parse("4:00pm")

Every day at 08:00, 13:00, and 18:00


  EventSpecification.create :description => 'walk the dog',
    :start_at => Time.parse("8:00am"),
    :repeat => :per_hour,
    :target => [8,13,18]

Every day


  EventSpecification.create :description => 'eat breakfast',
    :start_at => Time.parse("7:30am"),
    :repeat => :daily

Every three days


  EventSpecification.create :description => 'call mom',
    :start_at => Time.parse("10:30am"),
    :repeat => :daily,
    :frequency => 3

On Monday, Wednesday, and Friday of each week


  EventSpecification.create :description => 'go to the gym',
    :start_at => Time.parse("6:30am"),
    :repeat => :weekly,
    :on => [ :mo, :we, :fr ]

On Thursday, every other week


  EventSpecification.create :description => 'clean the bathroom',
    :start_at => Time.parse("8:00pm"),
    :repeat => :weekly,
    :frequency => 2, :on => [ :th ]

On the 10th and 25th of each month


  EventSpecification.create :description => 'pick up paycheck',
    :start_at => Time.parse("9:30am"),
    :repeat => :monthly,
    :on => [ 10, 25 ]

On the last Saturday of each month


  EventSpecification.create :description => 'run a marathon',
    :start_at => Time.parse("6:30am"),
    :repeat => :monthly,
    :on_the => :last,
    :target => [ :sa ]

On the last weekday of each month


  EventSpecification.create :description => 'wine tasting',
    :start_at => Time.parse("6:30pm"),
    :repeat => :monthly,
    :on_the => :last,
    :target => :wkday

Every April 15th


  EventSpecification.create :description => 'pay taxes',
    :start_at => Time.parse("4/15/2010 5:00pm"),
    :repeat => :yearly

On the second Thursday in May, every other year, until Dec 31, 2012


  EventSpecification.create :description => 'freak out',
    :start_at => Time.zone.now,
    :repeat => :yearly,
    :frequency => 2,
    :on => [ 5 ],
    :on_the => :second,
    :target => [ :th ],
    :until => Time.parse("12/31/2012")

Using the Rake task

A rake task is included to generate occurrences of recurring events. For example, you might run this out of a cron job each day to generate any recurring events for the next 30 days, or whatever.


  rake acts_as_event_owner:generate_events FROM=9/1/2010 TO=10/1/2010

Credits

ActsAsEventOwner was developed for Josh Pigford and Sabotage Media LLC, for use in their excellent Critterly product. Big thanks to Josh and Sabotage for agreeing to make ActsAsEventOwner available by open source!