justinfrench / activetime
- Source
- Commits
- Network (1)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Branch:
master
| name | age | message | |
|---|---|---|---|
| |
MIT-LICENSE | Mon Dec 29 06:00:19 -0800 2008 | |
| |
README.textile | Thu Jan 01 23:15:33 -0800 2009 | |
| |
Rakefile | Wed Dec 31 05:37:26 -0800 2008 | |
| |
init.rb | Thu Jan 01 05:07:31 -0800 2009 | |
| |
install.rb | Mon Dec 29 06:00:19 -0800 2008 | |
| |
lib/ | Thu Jan 01 05:10:00 -0800 2009 | |
| |
tasks/ | Mon Dec 29 06:00:19 -0800 2008 | |
| |
test/ | Thu Jan 01 05:07:31 -0800 2009 | |
| |
uninstall.rb | Mon Dec 29 06:00:19 -0800 2008 |
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.
