Rails STI using ONE form

polymorphism, ruby-on-rails, single-table-inheritance

Solution

I found a solution at http://coderrr.wordpress.com/2008/04/22/building-the-right-class-with-sti-in-rails/#comment-1826

class GenericClass < ActiveRecord::Base
  class << self
    def new_with_cast(*a, &b)
      if (h = a.first).is_a? Hash and (type = h[:type] || h['type']) and (klass = type.constantize) != self
        raise "wtF hax!!"  unless klass < self  # klass should be a descendant of us
        return klass.new(*a, &b)
      end

      new_without_cast(*a, &b)
    end
    alias_method_chain :new, :cast
  end
end

Which worked great for me with minimal code - I don't know if its hackish or not but it works, and is rather clean. I liked the fact that its only 10ish lines of code.

Problem

I have a form that allows me to add files of different formats to a stream. So, a stream is made up of many files, these files are XML files but basically have different schemas. I have one form that allows the user to add whatever file they want, I am using STI (which works great when data is already in the table), my trouble is adding the data to the table. The form has 1 input field, just a file_field that allows the user to select the file they want to upload. Since I only have one form I'm not able to instantiate the correct object, I have to do it programatically.. and I'm not sure how to do it. Do I just (or can I) add a drop down with the possible types, and call that field 'type' so that when the form is submitted rails will instantiate the write type of object because the type attribute is provided? What is the best practice for this.. I'm running rails 2.3.4.

Original source