Some Rails plugins: acts_as_catalog
As stated yesterday, I have recently worked on some plugins for Ruby on Rails, and I do think they are usable (and useful!) for audiences larger than myself. So, today I’ll present here the second such plugin. acts_as_catalog implements a really simple but really common pattern - Catalog-tables (or should I say catalog-models?) Granted, the amount of code this plugin saves is not very large, but it does add maintainability for our code-base, and includes basic unit tests. Of course, you can also taka a look at its SVN repo.
Models
A catalog is defined as a table with only a name column of string type, and with a unique index on it (this means, does not allow for duplicate values). Of course, more attributes can be added to a model which acts_as_catalog - they will just be ignored by this plugin. This plugin allows you to specify your model definition as:
def Mytable < ActiveRecord::Base
acts_as_catalog
belongs_to :some_other_table
end
A catalog is often accessed to populate i.e. drop-down selection or radio boxes, passing what is called collections in Rails-speak. You will often want collections to be sorted by ID or by name, thus:
collection = Mytable.collection_by_id
another_col = Mytable.collection_by_name </code>
Migrations
You can specify all the catalogs you need to create for a specific migration with a single instruction from inside your self.up method, by giving a list of catalog table names to create_catalogs:
def self.up
create_catalogs :countries, :states
...
end
Likewise, you can destroy the created catalogs in a single command. The
drop_catalogs method will usually be the last thing you call in self.down:
def self.down
...
drop_catalogs :states, :countries
end
Tests
This plugin provides the base functionality to include in your unit tests ensuring the catalog is properly declared. Just include ‘catalog_test_helper’ and include the CatalogTest mixin in your test classes, declare the model name, and off you go. This is, a complete unit test for you Mytable catalog model could be:
require File.dirname(__FILE__) + '../test_helper'
require 'catalog_test_helper'
class MytableTest < Test::Unit::TestCase include CatalogTestHelper def setup @model = Mytable end end </code>