I finally got it! Thank you both amikazmi and Topher Fangio. I had to implement both the delegate and method_missing techniques to get this to work.
Here is the total madness that finally ended up working for me! If anybody has suggestions on how to further improve this, I'd love to hear your suggestions.
class User < ActiveRecord::Base
attr_accessible *([:user_name, :udid, :password, :password_confirmation, :contact_info] + ContactInfo.accessible_attributes.to_a.map {|a| a.to_sym})
has_one :contact_info, :as => :contactable
def method_missing(method_id, *args)
if (!self.respond_to?(method_id) && self.contact_info.respond_to?(method_id))
self.contact_info.send(method_id, *args)
elsif (!self.class.respond_to?(method_id) && ContactInfo.respond_to?(method_id))
ContactInfo.send(method_id, *args)
else
super(method_id, *args)
end
end
# delegating attributes seems redundant with the method_missing above, but this secret sauce works.
ContactInfo.accessible_attributes.to_a.each do |a|
delegate a.to_sym, "#{a}=".to_sym, :to => :contact_info
end
def initialize(*args)
options = args.extract_options!
contact_attrs = ContactInfo.accessible_attributes.to_a.map{|a| a.to_sym}
@ci = ContactInfo.new(options.reject {|k,v| !contact_attrs.include?(k) })
super(*(args << options.reject { |k,v| contact_attrs.include?(k) }.merge(:contact_info => @ci) ) )
self.contact_info = @ci
end
validates_presence_of :user_name
validates_uniqueness_of :user_name
validates_associated :contact_info
def after_save
# automatically save the contact info record for the user after the user has been saved.
self.contact_info.save!
end
end
class ContactInfo < ActiveRecord::Base
set_table_name "contact_info"
belongs_to :contactable, :polymorphic => true
validates_presence_of :email
validates_uniqueness_of :email
attr_accessible :first_name,
:last_name,
:middle_initial,
:title,
:organization_name,
:email,
:email_2,
:twitter_name,
:website_url,
:address_1,
:address_2,
:city,
:state,
:zip,
:phone_work,
:phone_mobile,
:phone_other,
:phone_other_type
def full_name
[self.first_name, self.last_name].compact.join(' ')
end
end