Skip to content

Rails plugin providing a parent object for has_many associations based on time, rather than a foreign key.

License

Notifications You must be signed in to change notification settings

justinfrench/activetime

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

Rails plugin providing a parent object for has_many associations based on time, rather than a foreign key.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages