Yet Another request to help DRY some code

Basically, I’m looking for a hook that will let me iterate through all
my has_one relationships.

The idea of this class is that each PageAttribute should have exactly
one XX_page_attribute. There are several possibilities for this, so
it’s supposed to be encapsulated by the att_value attribute. (and
attribute that returns and sets the proper XX_page_attribute) the
decision about which XX_page_attribute is based on another column of
PageAttribute: class_name.

any ideas?
thanks,
Jacob

class PageAttribute < ActiveRecord::Base

belongs_to :page

has_one :boolean_page_attribute, :class_name =>
‘BooleanPageAttribute’, :dependent => :destroy
has_one :date_page_attribute, :class_name => ‘DatePageAttribute’,
:dependent => :destroy
has_one :string_page_attribute, :class_name => ‘StringPageAttribute’,
:dependent => :destroy
has_one :page_link_page_attribute, :class_name =>
‘PageLinkPageAttribute’, :dependent => :destroy
has_one :uploaded_file_page_attribute, :class_name =>
‘UploadedFilePageAttribute’, :dependent => :destroy

def att_value
if(self.class_name.to_s == ‘BooleanPageAttribute’)
return self.boolean_page_attribute
end
if(self.class_name.to_s == ‘DatePageAttribute’)
return self.date_page_attribute
end
if(self.class_name.to_s == ‘StringPageAttribute’)
logger.debug “returning string_page_attribute” +
string_page_attribute.to_s
return self.string_page_attribute
end
if(self.class_name.to_s == ‘PageLinkPageAttribute’)
return self.page_link_page_attribute
end
if(self.class_name.to_s == ‘UploadedFilePageAttribute’)
return self.uploaded_file_page_attribute
end
end

def att_value=(val)
logger.debug("setting att_value from: " + val.to_s);

if(self.class_name.to_s == 'BooleanPageAttribute')
  if val.is_a? Hash
    self.boolean_page_attribute = BooleanPageAttribute.new(val)
  else
    self.boolean_page_attribute = val
  end
end
if(self.class_name.to_s == 'DatePageAttribute')
  if val.is_a? Hash
    self.date_page_attribute = DatePageAttribute.new(val)
  else
    self.date_page_attribute = val
  end
end
if(self.class_name.to_s == 'StringPageAttribute')
  if val.is_a? Hash
    self.string_page_attribute = StringPageAttribute.new(val)
  else
    self.string_page_attribute = val
  end
end
if(self.class_name.to_s == 'PageLinkPageAttribute')
  if val.is_a? Hash
    self.page_link_page_attribute = PageLinkPageAttribute.new(val)
  else
    self.page_link_page_attribute = val
  end
end
if(self.class_name.to_s == 'UploadedFilePageAttribute')
  if val.is_a? Hash
    self.uploaded_file_page_attribute =

UploadedFilePageAttribute.new(val)
else
self.uploaded_file_page_attribute = val
end
end
end

On Nov 7, 2006, at 10:26 AM, [email protected] wrote:

Basically, I’m looking for a hook that will let me iterate through all
my has_one relationships.

http://rdoc.caboo.se/doc/classes/ActiveRecord/Reflection/
ClassMethods.html

In particular, you probably want to look at
reflect_on_all_associations(:has_one)

The idea of this class is that each PageAttribute should have exactly
one XX_page_attribute. There are several possibilities for this, so
it’s supposed to be encapsulated by the att_value attribute. (and
attribute that returns and sets the proper XX_page_attribute) the
decision about which XX_page_attribute is based on another column of
PageAttribute: class_name.

any ideas?
thanks,
Jacob

Hope that helps.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On 11/7/06, [email protected] [email protected] wrote:

PageAttribute: class_name.

This sounds like a classic use case for STI - have you considered using
that?
Essentially, all the various models (BooleanPageAttribute, etc.) would
look
like
this:

class BooleanPageAttribute < PageAttribute

any extra stuff

end

And PageAttribute would be:

class PageAttribute < ActiveRecord::Base
belongs_to :page
inheritance_column :class_name
end

(If you name your type indicator “type”, then you don’t need the
inheritance_column statement)

The schema for the page_attributes table would contain all of the data
from
the various types.
The att_value methods above would be replaced with the normal
page_attribute
(from belong_to)
methods on Page. And you can use the standard create()/new() syntax to
initialize PageAttributes;
just call them on the desired type. Example:

p = Page.new()
p.page_attribute = BooleanPageAttribute.new(options)

etc.

Alternately, you could always use a serialized column to store a typed
object opaquely (see
the discussion in AWDWR, and/or the AR docs). This loses a lot of
searchability, however.

And if you’re stuck with this as a legacy schema, well, we’ll pray for
you… :slight_smile:

Hope this helps,

Matt J.
[email protected]
President/Technical Director, Acme Art Company (acmeartco.org)