July 18, 2009 Leave a comment
While working on some code maintenance for PlanHQ I noticed a prime opportunity to refactor some code in the spirit of keeping the code DRY. There was code in both the controller action and in mailer methods that created a short paragraph of text describing what fields had been edited on several models for the purposes of both logging this for users to reference later, and to send email notifications.
My solution for this problem was to create this plugin (code available on github) which extends ActiveRecord::Base to provide a few simple methods on instances of your models to generate this text summary of the changes, before the model is saved back to the database (taking advantage of the code in the ActiveRecord::Dirty module). The plugin provides an easy way to customise the messages that are displayed and their format, and handles belongs_to associations nicely as well: Given a Task model that belongs_to a User model, re-assigning a task would produce the message “user has been changed from ‘Jeremy’ to ‘Jordan’” rather than the less informative “user_id has changed from 1 to 2″. See the README for more details on usage.
Usage: see the README for more
# Item.rb class Item < ActiveRecord::Base belongs_to :person custom_message_for :person, :display => :username custom_message_for :due_on, :as => "Due Date", :message => "has been rescheduled", :format => :pretty_print_date # this method is used for formatting the due_on field when it changes def pretty_print_date(value = self.due_on) value.strftime("%d/%m/%Y") end end
# ItemsController.rb class ItemsController < ApplicationController def update @item.attributes = params[:item] Mailer.deliver_item_update(@item, @item.change_messages.to_sentence) @item.save! end end