I often find myself writing repetitive bunches of methods for setting boolean attributes and retrieving records based on them. For example:
class Order < ActiveRecord::Base
def self.paid
find_all_by_paid(1)
end
def self.unpaid
find_all_by_paid(0)
end
def mark_as_paid
update_attribute(:paid, 1)
end
def mark_as_unpaid
update_attribute(:paid, 0)
end
end
This patch lets ActiveRecord provide such methods out-of-the-box by extending ActiveRecord::Base#method_missing. It gives you dynamic attribute-based finders and markers that can be chained together, as in
Order.paid_and_delivered
country.mark_as_hot_and_sunny
or made negative using prefixes, like
Order.unpaid
user.mark_as_irresponsible
Ending mark_as calls with '!' saves the changes to the database, while omitting the '!' just sets the attributes to true/false without saving. If you specify after_mark_as_xxx callbacks on your models, these will be called as appropriate.
The patch contains full documentation of these new features and updated unit tests. I have only tested this with MySQL so far, and would greatly appreciate testing with other DBs. Also, there is one bug I'm not sure how to correct - this is commented in the unit tests, see the diff for more info.