Search

Enter a search word or two and press return to see the search results.

Who am I?

Hi, I’m Graeme and these are my notes, from my messy desk. I started this blog because Google proved to be more useful at finding content than anything else I’ve used.

So I started adding my own content in the hopes that Google would index it and allow me to find things again in the future.

It works.

You can find out more about me here, and you should follow me on Twitter here.

Keeping up

You can automatically receive new content here by subscribing to the “Blog RSS” (link below). This is the easiest way to keep up with what I write here.  See this BBC article for a good introduction on RSS and keeping up with the goings on of the Internet more easily.

« Read-only clones and committing changes to submodules | Main | Using git submodules to track plugins »
Thursday
Apr102008

Timestamps that can behave like booleans

I often come across this particular use case and it's probably easiest to
explain with an example. Take an ActiveRecord model called `Book` which
represents a book in Amazon's catalogue. In addition to books which are
already published, we collect information about books which are going to be
released at some point in the future. We store the publication date in the
field `published_at`.

More often than not, though, we don't really want to know *when* a book was
(or will be) published, we just want to know whether it has been published or
not. So I wind up defining a couple of extra methods:

class Book < ActiveRecord::Base
def published?
!published_at.blank?
end

def published=(value)
# Note the automatic time zone conversion magic in edge rails!
self.published_at = value ? Time.now : nil
end
end

All well and good, but I wind up doing that quite a few times across all the
projects I have. Time for an extraction! And what's good about this
extraction? Well, it expresses what I am actually trying to do without boring
you with the details of how I do it. So how about:

class Book < ActiveRecord::Base
timestamped_boolean :published_at
end

Now we get the two methods defined automatically. And, as I say, we have a
declarative way of saying what we're providing without having to have extra
documentation.

I've pulled this abstraction into a tiny wee plugin which is now up on GitHub.
It's called
[`timestamped_booleans`](http://github.com/rubaidh/timestamped_booleans). Feel
free to grab it, fork it, play around. I've got a couple of changes I should
do and push in the next few hours. The first you'll already have noticed if
you're reading carefully; what if the date it is `published_at` is in the
future? It's not published then, is it? So I'll need to modify the question
method to also check that the attribute's date is not in the future.

Next up after that is to automatically declare associated named scopes for
edge Rails because I also wind up doing the equivalent as class methods a lot:

class Book :conditions => { ['published_at IS NOT ?'], nil} do
yield
end
end
end

which it wouldn't hurt to tidy up a bit.

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments (2)

heya - we use that pattern a bit here too. We have a system that allows orders to be stored in varying states - most notably "editable", "submitted" and "completed". So we have two of thosed boolean-timestamps: submitted_at and completed_at and have been doing something pretty similar to the above for some time now.

However I've been using the autoscope plugin to restrict scope rather than rolling my own scoping method.

Recently we're about to add a few more states in, so it's time for us to move over to acts_as_state_machine. But as a simple way of keeping state - you can't beat this method.

April 11, 2008 | Unregistered CommenterTaryn East

I've done something similar with a module (in app/models/shared/publishable_model.rb). Including the module adds a named scope (has_finder), the instance method


def published?
published_at?
end

, some methods to publish/unpublish etc.

This is a great fit for us.

I've been http://henrik.nyh.se/2008/02/rails-model-extensions" rel="nofollow">using modules more and more in Rails.

April 14, 2008 | Unregistered CommenterHenrik N

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>