Atlrug-billsiggelkow-20071212

  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Atlrug-billsiggelkow-20071212 as PDF for free.

More details

  • Words: 560
  • Pages: 15
Generic Lookups in Rails A brief walk thru time and space ... Words and Music by Bill Siggelkow

About Me My last name is pronounced Siggelkōw, not cow. Please ignore the pesky “w” on the end. 1985 Graduate of the North Avenue Trade School. Reformed Fortran to C to Java Programmer. Author of the Jakarta Struts Cookbook (O’Reilly) Ruby/Rails for 2 years -- making a living at it since May ’07. Uncanny ability to store and recall loads of worthless information in my brain.

Lookups A person can have any number of “demographic” attributes that are “looked up” such as marital status, religion, and ethnicity. We want the set of valid values for each of these attributes types to be specified and maintained in our database. Implementing in code (using constants) requires redeployment to the server. Using the database gives us a place to hang “administration”.

Lookups Each lookup of a lookup type consists of: value (e.g. married), code (optional -- could be used for legacy integration) position (for support of acts_as_list) There is no additional data about the association between an entity and the lookup value. For example, we do not need to track the number of years a person has been married ...

Data Model v0.1 Value Code Marital Status First Name

marital_status_id

Person

religion_id

Position

Value Religion

Code Position

Last Name

ethnicity_id

Value Ethnicity

Code Position

Problems with Data Model v0.1 If we have new types of attributes (e.g. hair color), we have to create a whole new table. The model (and, therefore, the code) is not very DRY. Our Rails app will have umpteen models with identical attributes. (Even utilizing extension it’s still a lot of classes).

Data Model v0.2 marital_status_id First Name

Person Last Name

Value

religion_id

Lookup

ethnicity_id

Code

Position lookup_type_id LookupType

Name

lookup.rb # :lookup_type - the type of lookup # :value - a valid value # :code - an optional code (e.g. a numeric code used by some third-party) # :position - orders the lookups scoped to a given :name. (This permits # specific ordering of the lookup values for drop-downs and the like.)

class Lookup < ActiveRecord::Base belongs_to :lookup_type acts_as_list :scope => :lookup_type end

lookup_type.rb class LookupType < ActiveRecord::Base has_many :lookups, :order => 'position', :dependent => :delete_all do def by_value(value) find(:first, :conditions => {:value => value}) end end validates_uniqueness_of :name validates_presence_of :name end

person.rb (v0.1) class Person < ActiveRecord::Base belongs_to :marital_status, :class_name => ‘Lookup’, :foreign_key => ‘marital_status_id’ belongs_to :religion, :class_name => ‘Lookup’, :foreign_key => ‘religion_id’ .... end

Person v0.1 Problems

We DRYed up the lookups but now our Person class is not DRY. “Person belongs to marital status” sounds weird. A person should have a marital status, not belong to one.

Solution ... Monkey Patch Rails! module ActiveRecord module Associations module ClassMethods def has_lookup(association, options = {}) options.merge!( :class_name => 'Lookup', :foreign_key => "#{association}_id" ) self.belongs_to association, options end alias has_a has_lookup alias has_an has_a end end end

person.rb (v0.2)

class Person < ActiveRecord::Base has_a :marital_status has_a :religion has_an :ethnicity .... end

A View Helper for Drop-downs def select_from_lookup( object, method, options={}, html_options = {}) lookup_type = LookupType.find_by_name(method) choices = lookup_type.lookups.collect {|l| [l.value, l.id] } select( object, "#{method}_id", choices, options, html_options ) end -------------------------------------------------------------------------<%= select_from_lookup 'person', 'marital_status' %>

Questions and Comments

I’d like to say thank you on behalf of the group and ourselves and I hope we’ve passed the audition.