petehamilton / citier

CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for simple Multiple Class Inheritance in Rails.
88 stars 24 forks source link

Build associations with model type #39

Open jonlhouse opened 12 years ago

jonlhouse commented 12 years ago

I was trying to figure out how to use CITIER with accepts_nested_attributes_for such that I could create nested child models dynamically. For example:

List.new( items_attributes => 
  [ { ItemTypeA => { STUFF },
    { ItemTypeB => { STUFF },
 ])

I found some information from: http://stackoverflow.com/questions/2553931/can-nested-attributes-be-used-in-combination-with-inheritance (see response 1).

This lead me to a monkey-patch with the following:

class ActiveRecord::Reflection::AssociationReflection < ActiveRecord::Reflection::MacroReflection
  def build_association(*options, &block)
    @original_build_association_called = true
    if options.first.is_a?(Hash) and options.first[:model_type].presence
      build_klass = options.first[:model_type].to_s.constantize     # raises NameError
      build_klass.new(*options)                               # raises ActiveRecord::AssociationTypeMismatch
    else
      klass.new(*options, &block)
    end
  end
end

Now I can pass the :model_type param to create specific child instances when creating nested_attributes or from List.build(:model_type => ItemTypeA).

I hope that this helps anyone trying to do the same thing.

morgz commented 12 years ago

Hey.. looking at this now but just for a nested_attribute on a Root citier model (but adding through sub model form) where do you put this code?