Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Rails plugin providing a parent object for has_many associations based on time, rather than a foreign key.
Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
tasks
test
MIT-LICENSE
README.textile
Rakefile
init.rb
install.rb
uninstall.rb

README.textile

ActiveTime

ActiveTime is a Rails plugin that provides a parent object for has_many-ish associations to other ActiveRecord classes, but instead of a foreign key to scope the queries, a date range is used instead.

While this isn’t exactly how it all works, this should help visualize what I’m aiming for:

class Year
  has_many :posts
  has_many :comments
end

A few quick examples:

# All Posts created in 2008
Year.new(2008).posts

# All Posts created in the current year
Year.new(Time.now)

# All Comments created in November 2008
Month.new(2008, 11).comments

# All Comments created in the current month
Month.new(Time.now).comments

# All Users created on November 15, 2008
Day.new(2008, 11, 15).users

# All Users created in the current day
Day.new(Time.now).users

# You aren't stuck with created_at either
Year.new(2008).posts(:published_at)

# ActiveTime can be used instead
ActiveTime.new(2008).posts

# Which is helpful when you want a range between two specific dates/times
ActiveTime.new(1.year.ago.utc, Time.now.utc).comments

# And it's just a wrapper around a named_scope under the hood, so you can do normal stuff:
Year.new(2008).posts.public.newest_first.paginate

Installation

./script/plugin install git://github.com/justinfrench/activetime.git

Why?

I’m not sure why you need it, but I’m building some RESTful controllers that need to present resources in a hierarchy based on dates (rather than a typical has_many/belongs_to association), so I wanted a model for the resource, upon which I could do the usual ActiveRecord has_many associations, scope chaining, pagination, etc. I wanted something that felt like ActiveRecord a bit.

How?

Firstly, the plugin adds a named scope to ActiveRecord::Base (so it’s added to all your AR models) called in_date_range, which you can use directly if needed. It takes two Time objects in UTC as arguments (start time, end time) and optionally, a third argument that specifies which column the date range applies to (the default is :created_at). Examples:

Post.in_date_range(1.year.ago.utc, Time.now_utc)
Post.in_date_range(1.year.ago.utc, Time.now_utc, :published_at)

If you have two Time objects for the start and end of the range, ActiveTime is simply a wrapper around this named scope. These both result in the same database query:

Post.in_date_range(1.year.ago.utc, Time.now_utc)
ActiveTime.new(1.year.ago.utc, Time.now.utc).posts

Given that the second version is two characters longer, it’s not all that impressive, but what I really needed was to pass in just the start date, or part of one (like params[:year]) and automatically figure out what range I wanted (a whole year, a month, a day).

Year.new(params[:year]).posts
Month.new(params[:year], params[:month]).posts

And there’s more!

  
# Get the calculated start and end times:
Year.new(2008).starting             # => Tue Jan 01 00:00:00 UTC 2008
Year.new(2008).ending               # => Wed Dec 31 23:59:59 UTC 2008

# Get a description of the range
Year.new(2008)                      # => in 2008
Month.new(2008, 11)                 # => in November 2008
Day.new(2008, 11, 18)               # => on November 18 2008

Status

It’s pretty fresh and not battle tested yet, but the test suite is pretty solid. There’s heaps more to come, but what’s there right now works great.

Next

  • tidy up the code a bit
  • generate and publish the rdoc
  • support hour, minute and second (Rails doesn’t provide #at_end_of_hour out of the box, so I’m just being lazy so far)
  • parse more date formats for input
  • time zones? (everything assumes UTC right now)
  • localization / internationalization?
  • anything better than method_missing magic (something more declarative)?

Project Info

ActiveTime is hosted on Github, where your contributions, forkings, comments and feedback are greatly welcomed.

Copyright © 2008 Justin French, released under the MIT license.

Something went wrong with that request. Please try again.