aux codes ========= Way back when, when I was learning database development, a mentor of mine showed me a technique that he liked to use to consolidate similar enumeration-esque database tables. Often, applications have enumeration-esque tables that merely store simply key / value pairs, typically a unique ID and a string. Take for instance, a `genders` table: [ genders ] [id] [name] 1 Male 2 Female That's a bit of a waste of a table, *especially* if your application has *TONS* of tables just like this. There's where aux codes (or auxilary codes) come in! [ aux_codes ] [id] [category_id] [name] 1 0 Genders <--- this defines a 'table' (because category_id = 0) 2 1 Male <--- these are under category_id 1 (Genders) 3 1 Female 4 0 Colors <--- defines a color 'table' 5 4 Red <--- category_id 4 = 'Colors', so this is a color 6 4 Blue Simple, eh? Now, this is great, but this might get in the way of our business logic or it might dirty up our code. We don't want to always be using the AuxCode object with complex queries ... we probable want a Gender object that behaves just like it would with a full-blown genders table. Gender = AuxCode.category('Gender').aux_code_class # the Gender class is a full-blown ActiveRecord class # that should behave as if there's actually a `genders` table! Gender.find_by_name 'Male' Gender.find_or_create_by_name 'Female' Gender.create :name => 'Female' male = Gender.new :name => 'Male' male.save Gender.find :conditions => ['name = ?', 'Male'] Gender.count Gender.codes Gender.code_names Gender.aux_code Gender.aux_codes If you want to create all of these classes at once, as constants: AuxCode.create_classes! You can also access codes with a Hash-like syntax AuxCode['Genders']['Male'] AuxCode[:Genders][:Female] Gender[:Male] Or with an Indifferent Hash-like syntax AuxCode.genders['Male'] AuxCode.genders[:Male] AuxCode.genders.male Gender.male # these all return the same result Breed.find_by_name 'Golden Retriever' Breed['Golden Retriever'] Breed[:golden_retriever] Breed.golden_retriever AuxCodes.breeds.golden_retriever TODO ---- - make a spec specifically for showing off the different API features quickly and easily - convert this README to RDoc - custom fields, eg: - `Breed#acronym` - `Breed#description` - `Breed#kennel_association_id` ... - these need an easy way to be defined! `alias_attribute`? - this needs to work in development mode, when the models are constantly being reloaded! - you shouldn't have to know the name of the special field to use it ... something like `attr_string :name` could just grab the (first) string column! - should we have a field for misc serialized meta-data? could be abused ... but could also be helpful ... - create (or update) method(s) for helping with the original AuxCode migration and for creating the special additional fields - make table name and column names configurable (but with strong defaults) - should have a rails generator ... should be 1 command to setup `aux_codes` in Rails - after i add a rails generator, i'll bump to 1.1.0 and release NOTES ----- this implementation is for ActiveRecord only! i hope to eventually make a similar DataMapper implementation